libe3 0.2.5
C++ library for E3AP RAN vendor integration
Loading...
Searching...
No Matches
e3_dapp_session.hpp File Reference

Python-facing dApp session over libe3 — batched, low-latency seam. More...

#include <libe3/types.hpp>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>

Go to the source code of this file.

Classes

struct  libe3::py::E3Event
 One inbound E3AP event, POD-flat for a clean SWIG crossing. More...
class  libe3::py::DAppSession
 dApp-role E3AP session with a batched, lock-free inbound ring. More...

Namespaces

namespace  libe3
namespace  libe3::py

Enumerations

enum  libe3::py::E3EventKind {
  libe3::py::E3_EVENT_NONE = 0 , libe3::py::E3_EVENT_INDICATION = 1 , libe3::py::E3_EVENT_XAPP_CONTROL = 2 , libe3::py::E3_EVENT_SUBSCRIPTION_RESPONSE = 3 ,
  libe3::py::E3_EVENT_SETUP_RESPONSE = 4 , libe3::py::E3_EVENT_MESSAGE_ACK = 5
}
 Discriminator for E3Event. More...

Detailed Description

Python-facing dApp session over libe3 — batched, low-latency seam.

Why this class exists

libe3's core libe3::E3Agent drives the dApp role with std::function handlers (libe3::E3Agent::set_indication_handler et al.). SWIG cannot bridge those callbacks to Python across libe3's inbound worker threads without either running Python under the GIL on the hot thread (directors — deadlock-prone, serialises dispatch) or paying a GIL round-trip per message. Both are unacceptable at the E3AP target rate (real-time, sub-millisecond cadence, very high message throughput).

libe3::py::DAppSession is the answer: it owns an libe3::E3Agent in DAPP role, registers the C++ handlers itself, and funnels every inbound message into a bounded lock-free ring (libe3::LockFreeQueue). Python drains that ring in batches via poll_events, so one GIL acquire and one Python↔C++ boundary crossing are amortised across many messages. The SWIG wrapper releases the GIL around the blocking calls (see swig/libe3.i, module(threads="1")), so libe3's C++ threads never stall on Python.

The E3SM (service-model) payloads stay opaque here (std::vector<uint8_t>); dApp-library encodes/decodes them in Python. This class is E3AP only, mirroring the OAI split where libe3 owns E3AP and the SM owns encode/decode.

Lifecycle

ctor (registers handlers) → start → wait_for_setup → (read setup via dapp_id / setup accessors) → subscribe → loop: poll_events + send_control / send_report → release → stop.

Rejected alternatives (auditable)

  • SWIG directors: run the Python callback on libe3's inbound thread under the GIL — serialises dispatch, deadlock-prone if Python re-enters libe3.
  • per-message poll: one GIL round-trip + one boundary crossing per message caps throughput; batching is strictly better with no added latency (the ring still wakes on the first event).

SPDX-FileCopyrightText: Copyright (c) 2026 Northeastern University SPDX-License-Identifier: Apache-2.0

Definition in file e3_dapp_session.hpp.