13#ifndef LIBE3_E3_INTERFACE_HPP
14#define LIBE3_E3_INTERFACE_HPP
29#include <condition_variable>
31#include <unordered_map>
122 return *subscription_manager_;
129 return *response_queue_;
152 dapp_report_handler_ = std::move(handler);
156 dapp_status_changed_handler_ = std::move(handler);
161 setup_response_handler_ = std::move(handler);
164 subscription_response_handler_ = std::move(handler);
167 indication_handler_ = std::move(handler);
170 xapp_control_handler_ = std::move(handler);
173 message_ack_handler_ = std::move(handler);
177 std::optional<uint32_t>
dapp_id() const noexcept;
187 std::vector<uint32_t> telemetry_ids,
188 std::vector<uint32_t> control_ids,
189 std::optional<uint32_t> sub_time = std::nullopt,
190 std::optional<uint32_t> periodicity = std::nullopt,
191 uint32_t* out_request_id =
nullptr);
198 std::vector<uint8_t> action_data,
199 uint32_t sequence_id = 0,
200 uint32_t* out_message_id =
nullptr);
202 std::vector<uint8_t> report_data,
203 uint32_t sequence_id,
204 uint32_t* out_message_id =
nullptr);
219 std::atomic<bool> should_stop_{
false};
224 std::atomic<uint32_t> next_message_id_{0};
227 std::unique_ptr<E3Connector> connector_;
228 std::unique_ptr<E3Encoder> encoder_;
230 std::unique_ptr<SubscriptionManager> subscription_manager_;
232 std::unique_ptr<DAppSubscriptionState> dapp_state_;
239 struct PendingSubscriptionOp {
240 uint32_t ran_function_id{0};
241 bool is_delete{
false};
243 std::mutex pending_subscriptions_mutex_;
244 std::unordered_map<uint32_t, PendingSubscriptionOp> pending_subscriptions_;
245 std::unique_ptr<LockFreeQueue<Pdu>> response_queue_;
249 std::unique_ptr<LockFreeQueue<DAppReport>> report_queue_;
255 std::unique_ptr<std::thread> setup_thread_;
256 std::unique_ptr<std::thread> inbound_thread_;
257 std::unique_ptr<std::thread> outbound_thread_;
258 std::unique_ptr<std::thread> report_worker_thread_;
259#ifdef LIBE3_ENABLE_LATREC
263 std::unique_ptr<std::thread> context_thread_;
278 mutable std::mutex setup_complete_mu_;
279 std::condition_variable setup_complete_cv_;
280 bool setup_complete_{
false};
281 bool setup_succeeded_{
false};
290 void setup_loop_ran();
295 void setup_loop_dapp();
300 void inbound_loop_ran();
306 void inbound_loop_dapp();
312 void outbound_loop_ran();
318 void outbound_loop_dapp();
325 void report_worker_loop();
327#ifdef LIBE3_ENABLE_LATREC
331 void context_monitor_loop();
339 void handle_setup_request(
const SetupRequest& request, uint32_t request_message_id);
340 void handle_subscription_request(
const SubscriptionRequest& request, uint32_t request_message_id);
341 void handle_subscription_delete(
const SubscriptionDelete& del, uint32_t request_message_id);
342 void handle_control_action(
const DAppControlAction& action, uint32_t request_message_id,
343 uint64_t latrec_seq);
344 void handle_dapp_report(
const DAppReport& report);
345 void handle_release_message(
const ReleaseMessage &release);
346 void handle_dapp_disconnection(uint32_t
dapp_id);
366 void send_negative_setup_reply(uint32_t request_id);
369 void handle_setup_response(
const SetupResponse& response);
370 void handle_subscription_response(
const SubscriptionResponse& response);
371 void handle_indication(
const IndicationMessage& msg, uint64_t latrec_seq);
372 void handle_xapp_control_action(
const XAppControlAction& action, uint64_t latrec_seq);
373 void handle_message_ack(
const MessageAck& ack);
382 void on_sm_lifecycle_change(uint32_t ran_function_id,
bool should_start);
391 void remember_subscription_op(uint32_t request_id, uint32_t ran_function_id,
395 void forget_subscription_op(uint32_t request_id);
E3Agent - Main façade for RAN vendor integration.
ErrorCode queue_dapp_report(uint32_t ran_function_id, std::vector< uint8_t > report_data, uint32_t sequence_id, uint32_t *out_message_id=nullptr)
void notify_dapp_status_changed()
ErrorCode queue_dapp_control_action(uint32_t ran_function_id, uint32_t control_id, std::vector< uint8_t > action_data, uint32_t sequence_id=0, uint32_t *out_message_id=nullptr)
ErrorCode init()
Initialize the interface.
std::vector< uint32_t > subscribed_ran_functions() const
LockFreeQueue< Pdu > & response_queue() noexcept
Get the response queue for outbound messages.
ErrorCode queue_outbound(Pdu pdu)
Queue a PDU for outbound transmission.
ErrorCode queue_subscription_delete(uint32_t ran_function_id)
E3Interface & operator=(E3Interface &&)=delete
SubscriptionManager & subscription_manager() noexcept
Get the subscription manager.
void set_dapp_status_changed_handler(DAppStatusChangedHandler handler)
~E3Interface()
Destructor - ensures clean shutdown.
void set_indication_handler(IndicationHandler handler)
bool is_running() const noexcept
Check if interface is running.
ErrorCode queue_subscription_request(uint32_t ran_function_id, std::vector< uint32_t > telemetry_ids, std::vector< uint32_t > control_ids, std::optional< uint32_t > sub_time=std::nullopt, std::optional< uint32_t > periodicity=std::nullopt, uint32_t *out_request_id=nullptr)
std::vector< uint32_t > get_available_ran_functions() const
Get available RAN functions.
uint32_t generate_message_id()
Generate the next message ID, monotonic within 1..4294967295.
ErrorCode start()
Start the interface processing loops.
E3Interface(const E3Interface &)=delete
AgentState state() const noexcept
Get current state.
ErrorCode wait_for_setup(std::chrono::milliseconds timeout)
void set_subscription_response_handler(SubscriptionResponseHandler handler)
ErrorCode queue_release_message()
E3Interface(const E3Config &config)
Construct with configuration.
E3Interface & operator=(const E3Interface &)=delete
void set_xapp_control_handler(XAppControlHandler handler)
void set_message_ack_handler(MessageAckHandler handler)
void stop()
Stop the interface.
void set_setup_response_handler(SetupResponseHandler handler)
std::vector< uint32_t > active_subscription_ids() const
E3Interface(E3Interface &&)=delete
std::vector< RanFunctionDef > remote_ran_functions() const
std::optional< uint32_t > dapp_id() const noexcept
void set_dapp_report_handler(DAppReportHandler handler)
uint32_t sanitize_request_message_id(uint32_t request_id)
Return a request id that can be echoed into a response.
ErrorCode register_sm(std::unique_ptr< ServiceModel > sm)
Register a Service Model.
Lock-free bounded blocking queue.
Per-instance state for the dApp role.
Abstract E3 Connector interface for transport layer.
Abstract E3 Encoder interface for PDU encoding/decoding.
Lock-free bounded blocking queue for the E3AP hot paths.
std::function< void(const SubscriptionResponse &)> SubscriptionResponseHandler
ErrorCode
Error codes returned by libe3 operations Use shared error-code list (see libe3/error_codes....
std::function< void(const XAppControlAction &)> XAppControlHandler
AgentState
Agent state machine states.
@ RUNNING
Main processing loop active.
@ UNINITIALIZED
Agent not yet initialized.
std::function< void()> DAppStatusChangedHandler
ResponseCode
E3AP response codes.
std::function< void(const DAppReport &)> DAppReportHandler
std::function< void(const SetupResponse &)> SetupResponseHandler
std::function< void(const MessageAck &)> MessageAckHandler
std::function< ResponseCode(const SubscriptionRequest &)> SubscriptionRequestHandler
std::function< ResponseCode(const SetupRequest &, SetupResponse &)> SetupRequestHandler
Callback types for E3Interface events.
std::function< void(const IndicationMessage &)> IndicationHandler
Service Model Interface - Extension point for RAN vendors.
E3AP dApp Report structure.
Configuration for E3Agent.
E3AP Indication Message structure.
E3AP Message Acknowledgment structure.
Generic E3AP PDU structure.
RAN Function Definition for Setup Response.
E3AP Setup Request structure.
E3AP Setup Response structure.
E3AP Subscription Request structure.
E3AP Subscription Response structure.
E3AP xApp Control Action structure.
E3 Subscription Manager for tracking dApp registrations.
E3AP Protocol Types - Vendor-neutral type definitions.