libe3 0.2.5
C++ library for E3AP RAN vendor integration
Loading...
Searching...
No Matches
c_api.h
Go to the documentation of this file.
1/*
2 * C API for libe3
3 * Minimal C-compatible wrappers to create an E3Agent and ServiceModel from C
4 *
5 * SPDX-FileCopyrightText: Copyright (c) 2026 Northeastern University
6 * SPDX-License-Identifier: Apache-2.0
7 */
8#ifndef LIBE3_C_API_H
9#define LIBE3_C_API_H
10
11#include <stdint.h>
12#include <stddef.h>
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18#include "libe3/error_codes.h"
19
20/* Opaque handles */
23
24
25/* Callback prototypes for a C-backed ServiceModel */
27typedef void (*e3_sm_destroy_cb)(void* sm_context);
29typedef void (*e3_sm_stop_cb)(void* sm_context);
30typedef int (*e3_sm_is_running_cb)(void* sm_context); /* returns 0/1 */
33 void* sm_context,
34 uint32_t request_message_id,
35 uint32_t dapp_id,
36 uint32_t ran_function_id,
37 uint32_t control_id,
38 const uint8_t* data,
39 size_t data_len,
40 /* Correlation id of the xApp procedure this control re-issues; 0 when the
41 dApp decided on its own and there is no procedure to report back to. */
42 uint32_t sequence_id
43);
44
45/* Callback for incoming dApp reports (dApp -> RAN). */
46typedef void (*e3_dapp_report_cb)(
47 uint32_t dapp_id,
48 uint32_t ran_function_id,
49 const uint8_t* report_data,
50 size_t report_data_len,
51 /* Correlation id the dApp assigned to this detection; 0 when unset. */
52 uint32_t sequence_id
53);
54
55/** Callback when dApp status changes (connect, disconnect, subscribe, unsubscribe). */
56typedef void (*e3_dapp_status_changed_cb)(void);
57
58/**
59 * @brief Set callback for dApp status changes.
60 *
61 * Called when a dApp connects, disconnects, subscribes, or unsubscribes.
62 * Pass NULL as \p handler to clear the callback.
63 *
64 * @param agent Agent handle
65 * @param handler Callback invoked on each dApp status change
66 * @return \ref e3_error_t (see \ref libe3::ErrorCode; 0 == SUCCESS)
67 */
69 e3_agent_handle_t* agent,
71);
72
73/**
74 * @brief Descriptor describing a ServiceModel implemented in C.
75 *
76 * - `name`, `version` and `ran_function_id` identify the SM.
77 * - `telemetry_ids` and `control_ids` point to arrays that will be copied
78 * by the implementation; the caller may free them after creating the SM.
79 * - `ran_function_data` is required and is copied by the implementation.
80 * - Callbacks are invoked by the C++ adapter and receive `user_data`.
81 */
82typedef struct {
83 const char* name; // Service Model name (null-terminated string)
84 uint32_t version; // Service Model version
85 uint32_t ran_function_id; // RAN function ID for this SM
86
87 const uint32_t* telemetry_ids; // Array of supported telemetry IDs (copied by library)
88 size_t telemetry_ids_len; // Number of telemetry IDs
89
90 const uint32_t* control_ids; // Array of supported control IDs (copied by library)
91 size_t control_ids_len; // Number of control IDs
92
93 /* Opaque RAN function data (E3SM-encoded, advertised in the setup response).
94 * Required, not optional: E3AP declares ranFunctionData as a mandatory
95 * OCTET STRING (SIZE (1..32768)), so registration is rejected if these
96 * fields describe an empty or oversized buffer. */
97 const uint8_t* ran_function_data; // Opaque RAN function data (must be non-NULL)
98 size_t ran_function_data_len; // Length in bytes; must be 1..32768
99
100 /* Callbacks */
101 e3_sm_init_cb sm_init; // Called on SM registration
102 e3_sm_destroy_cb sm_destroy; // Called on SM destruction
103 e3_sm_start_cb sm_start; // Called when SM should start
104 e3_sm_stop_cb sm_stop; // Called when SM should stop
105 e3_sm_is_running_cb sm_is_running; // Called to query running state
106 e3_sm_process_control_cb sm_process_control; // Called to process control actions
107
108 void* sm_context; // Opaque pointer passed to all callbacks
110
111/* Create/destroy a C-backed ServiceModel */
112/**
113 * @brief Create a ServiceModel implementation backed by C callbacks.
114 *
115 * The returned pointer owns a C++ `ServiceModel` instance. The caller
116 * retains ownership until the model is registered with an agent via
117 * `e3_agent_register_sm`, at which point ownership is transferred to the
118 * agent and `e3_service_model_destroy` will no longer free the object.
119 *
120 * @param desc Descriptor containing metadata and callback function pointers
121 * @return e3_service_model_handle_t* on success, NULL on allocation error
122 */
124 const e3_c_service_model_desc_t* desc
125);
126
127/**
128 * @brief Destroy a C-backed ServiceModel handle.
129 *
130 * If the model has been registered with an agent (ownership transferred),
131 * this function is a no-op and the agent takes responsibility for cleanup.
132 */
134
135/**
136 * @brief Emit an indication message from a ServiceModel to the outbound queue.
137 *
138 * This is intended for C-backed ServiceModels. The message is forwarded by
139 * the internal publisher path.
140 */
143 uint32_t dapp_id,
144 uint32_t ran_function_id,
145 const uint8_t* data,
146 size_t data_len
147);
148
149/**
150 * @brief Emit a message acknowledgment from a ServiceModel.
151 */
154 uint32_t request_id,
155 int response_code
156);
157
158/**
159 * @brief Configuration for creating an E3Agent from C.
160 *
161 * All string pointers are copied by the library; the caller may free them
162 * after the call. Use NULL for optional strings to keep library defaults.
163 *
164 * Enum values: link_layer: 0=ZMQ, 1=POSIX. transport_layer: 0=SCTP, 1=TCP, 2=IPC.
165 * encoding: 0=ASN1, 1=JSON. Use -1 for link_layer, transport_layer, encoding, log_level
166 * to keep defaults. Use 0 for setup_port, subscriber_port, publisher_port to keep defaults.
167 */
168typedef struct {
169 const char* ran_identifier;
170 int link_layer; /* 0=ZMQ, 1=POSIX, -1=default */
171 int transport_layer; /* 0=SCTP, 1=TCP, 2=IPC, -1=default */
172 uint16_t setup_port;
175 const char* setup_endpoint;
178 int encoding; /* 0=ASN1, 1=JSON, 2=PROTOBUF, -1=default */
179 size_t io_threads; /* 0=default */
180 int log_level; /* -1=default */
181 const char* log_path; /* NULL=auto (/tmp/e3_<role>[_<id>]_<euid>.log) */
182 /* A flag rather than a sentinel: core 0 is a legitimate target. */
183 int pin_io_threads; /* 0=no pinning */
184 int io_thread_affinity; /* logical core; Linux only, best-effort */
186
187/**
188 * @brief Create/destroy an `E3Agent` handle
189 */
190/**
191 * @brief Create a new `E3Agent` with a default configuration.
192 *
193 * The returned handle must be destroyed with `e3_agent_destroy` when no
194 * longer needed.
195 *
196 * @return e3_agent_handle_t* on success, NULL on allocation error
197 */
199
200/**
201 * @brief Create a new `E3Agent` with the given configuration.
202 *
203 * If \p config is NULL, behaves like \ref e3_agent_create_default.
204 * String fields in \p config are copied; the caller may free them after the call.
205 * Use 0 or NULL for fields to keep library defaults (e.g. setup_port 0 → 9990).
206 *
207 * @param config Configuration (ports, endpoints, link/transport layer, etc.)
208 * @return e3_agent_handle_t* on success, NULL on allocation error
209 */
211
212/**
213 * @brief Destroy an `E3Agent` handle.
214 *
215 * This will free the underlying resources. If the agent is currently
216 * running, callers should stop it with `e3_agent_stop` first.
217 */
219
220/* Agent operations */
221/**
222 * @brief Initialize the agent.
223 *
224 * Prepares internal resources; must be called before \ref e3_agent_start.
225 * Returns a \ref e3_error_t (see \ref libe3::ErrorCode; 0 == SUCCESS).
226 */
228
229/**
230 * @brief Start the agent processing threads and accept dApp connections.
231 *
232 * Returns a \ref e3_error_t (see \ref libe3::ErrorCode; 0 == SUCCESS).
233 */
235
236/**
237 * @brief Stop the agent and release runtime resources.
238 *
239 * Safe to call even if the agent is not running.
240 * Returns nothing; errors are ignored.
241 */
243
244/* Query agent state */
245/**
246 * @brief Get the agent state as an integer matching `libe3::AgentState`.
247 *
248 * Useful for callers in C to inspect agent status. Returns an `int` with
249 * the enum value; `AgentState::ERROR` is returned on invalid handle.
250 */
252
253/**
254 * @brief Query whether the agent is currently running.
255 *
256 * @return 1 if running, 0 otherwise (or on invalid handle)
257 */
259
260/**
261 * @brief Set callback for incoming dApp reports (dApp -> RAN).
262 *
263 * Pass NULL as \p handler to clear the callback.
264 *
265 * @param agent Agent handle
266 * @param handler Callback invoked for each incoming dApp report
267 * @return \ref e3_error_t (see \ref libe3::ErrorCode; 0 == SUCCESS)
268 */
270 e3_agent_handle_t* agent,
271 e3_dapp_report_cb handler
272);
273
274/* Helpers to return arrays allocated by the library. Caller must free with
275 * `e3_agent_free_uint32_array` when finished.
276 */
277/**
278 * @brief Return a newly-allocated array of available RAN function IDs.
279 *
280 * The returned array is allocated with `malloc` and the caller must free
281 * it with `e3_agent_free_uint32_array`. The number of elements is written
282 * to `out_len` if non-NULL. Returns NULL and sets `out_len` to 0 if there
283 * are no entries or the handle is invalid.
284 */
285uint32_t* e3_agent_get_available_ran_functions(e3_agent_handle_t* agent, size_t* out_len);
286
287/**
288 * @brief Return a newly-allocated array of registered dApp IDs.
289 *
290 * See `e3_agent_get_available_ran_functions` for ownership semantics.
291 */
292uint32_t* e3_agent_get_registered_dapps(e3_agent_handle_t* agent, size_t* out_len);
293
294/**
295 * @brief Return a newly-allocated array of RAN function IDs subscribed by a dApp.
296 *
297 * @param dapp_id dApp identifier to query
298 */
299uint32_t* e3_agent_get_dapp_subscriptions(e3_agent_handle_t* agent, uint32_t dapp_id, size_t* out_len);
300
301/**
302 * @brief Return a newly-allocated array of dApp IDs subscribed to a RAN function.
303 *
304 * @param ran_function_id RAN function identifier to query
305 */
306uint32_t* e3_agent_get_ran_function_subscribers(e3_agent_handle_t* agent, uint32_t ran_function_id, size_t* out_len);
307
308/**
309 * @brief Return a newly-allocated array of RAN function IDs that currently have
310 * at least one subscriber (RAN role).
311 *
312 * See `e3_agent_get_available_ran_functions` for ownership semantics.
313 */
314uint32_t* e3_agent_get_active_ran_functions(e3_agent_handle_t* agent, size_t* out_len);
315
316/**
317 * @brief Get the reporting periodicity a dApp requested for a RAN function.
318 *
319 * @return periodicity in microseconds, 0 if not set or subscription not found
320 */
322 e3_agent_handle_t* agent,
323 uint32_t dapp_id,
324 uint32_t ran_function_id
325);
326
327/**
328 * @brief Get the telemetry IDs a dApp requested for a RAN function.
329 *
330 * Caller must free the returned array with e3_agent_free_uint32_array().
331 *
332 * @param out_len receives the number of elements (set to 0 on error/empty)
333 * @return newly-allocated array, or NULL if empty/error
334 */
336 e3_agent_handle_t* agent,
337 uint32_t dapp_id,
338 uint32_t ran_function_id,
339 size_t* out_len
340);
341
342/**
343 * @brief Get the control IDs a dApp requested for a RAN function.
344 *
345 * Caller must free the returned array with e3_agent_free_uint32_array().
346 *
347 * @param out_len receives the number of elements (set to 0 on error/empty)
348 * @return newly-allocated array, or NULL if empty/error
349 */
351 e3_agent_handle_t* agent,
352 uint32_t dapp_id,
353 uint32_t ran_function_id,
354 size_t* out_len
355);
356
357/**
358 * @brief Free an array previously returned by the e3_agent_get_* helpers.
359 */
360void e3_agent_free_uint32_array(uint32_t* arr);
361
362/**
363 * @brief Send an indication message to a specific dApp.
364 *
365 * @param agent Agent handle
366 * @param dapp_id Target dApp identifier
367 * @param ran_function_id RAN function identifier
368 * @param data Pointer to E3SM-encoded payload (may be NULL)
369 * @param data_len Length of payload in bytes
370 * @return \ref e3_error_t (see \ref libe3::ErrorCode; 0 == SUCCESS)
371 */
373 e3_agent_handle_t* agent,
374 uint32_t dapp_id,
375 uint32_t ran_function_id,
376 const uint8_t* data,
377 size_t data_len
378);
379
380/**
381 * @brief Send an xApp control action to a specific dApp (e.g. from E2/SM).
382 *
383 * @param agent Agent handle
384 * @param dapp_id Target dApp identifier
385 * @param ran_function_id RAN function identifier
386 * @param control_data Pointer to E3SM-encoded control payload (may be NULL if data_len is 0)
387 * @param control_data_len Length of payload in bytes
388 * @param sequence_id Correlation id from the E2SM-DAPP control header; the dApp
389 * carries it back on the control it re-issues, which is how the RAN
390 * matches the applied control to the xApp procedure that asked for it.
391 * @return \ref e3_error_t (see \ref libe3::ErrorCode; 0 == SUCCESS)
392 */
394 e3_agent_handle_t* agent,
395 uint32_t dapp_id,
396 uint32_t ran_function_id,
397 const uint8_t* control_data,
398 size_t control_data_len,
399 uint32_t sequence_id
400);
401
402/**
403 * @brief Send a message acknowledgment (e.g. ack a control/request from dApp).
404 *
405 * @param agent Agent handle
406 * @param request_id ID of the request being acknowledged
407 * @param response_code 0 = positive (success), 1 = negative (failure)
408 * @return \ref e3_error_t (see \ref libe3::ErrorCode; 0 == SUCCESS)
409 */
411 e3_agent_handle_t* agent,
412 uint32_t request_id,
413 int response_code
414);
415
416/* Simple stats */
417/**
418 * @brief Number of registered dApps known to the agent.
419 */
421
422/**
423 * @brief Total number of active subscriptions tracked by the agent.
424 */
426
427/**
428 * @brief Register a `ServiceModel` implementation with the agent.
429 *
430 * Ownership of `sm` is transferred to the agent on success and callers
431 * must not free the handle after a successful call. On failure the caller
432 * retains ownership and should call `e3_service_model_destroy`.
433 *
434 * Fails with `E3_INVALID_PARAM` if the descriptor the handle was built
435 * from carried no `ran_function_data`, or more than 32768 bytes of it, and with
436 * `E3_SM_ALREADY_REGISTERED` if another SM already holds the same RAN
437 * function id.
438 *
439 * @return e3_error_t ErrorCode value (0 == success)
440 */
442 e3_agent_handle_t* agent,
444);
445
446#ifdef __cplusplus
447}
448#endif
449
450#endif // LIBE3_C_API_H
void(* e3_dapp_status_changed_cb)(void)
Definition c_api.h:56
void e3_agent_free_uint32_array(uint32_t *arr)
Free an array previously returned by the e3_agent_get_* helpers.
Definition c_api.cpp:376
e3_error_t e3_agent_register_sm(e3_agent_handle_t *agent, e3_service_model_handle_t *sm)
Register a ServiceModel implementation with the agent.
Definition c_api.cpp:242
struct e3_agent_handle_s e3_agent_handle_t
Definition c_api.h:21
e3_service_model_handle_t * e3_service_model_create_from_c(const e3_c_service_model_desc_t *desc)
Create a ServiceModel implementation backed by C callbacks.
Definition c_api.cpp:127
void(* e3_dapp_report_cb)(uint32_t dapp_id, uint32_t ran_function_id, const uint8_t *report_data, size_t report_data_len, uint32_t sequence_id)
Definition c_api.h:46
uint32_t e3_agent_get_subscription_periodicity(e3_agent_handle_t *agent, uint32_t dapp_id, uint32_t ran_function_id)
Get the reporting periodicity a dApp requested for a RAN function.
Definition c_api.cpp:345
uint32_t * e3_agent_get_ran_function_subscribers(e3_agent_handle_t *agent, uint32_t ran_function_id, size_t *out_len)
Return a newly-allocated array of dApp IDs subscribed to a RAN function.
Definition c_api.cpp:333
void e3_agent_destroy(e3_agent_handle_t *agent)
Destroy an E3Agent handle.
Definition c_api.cpp:222
e3_error_t(* e3_sm_process_control_cb)(e3_service_model_handle_t *sm_handle, void *sm_context, uint32_t request_message_id, uint32_t dapp_id, uint32_t ran_function_id, uint32_t control_id, const uint8_t *data, size_t data_len, uint32_t sequence_id)
Definition c_api.h:31
void(* e3_sm_destroy_cb)(void *sm_context)
Definition c_api.h:27
void e3_agent_stop(e3_agent_handle_t *agent)
Stop the agent and release runtime resources.
Definition c_api.cpp:237
size_t e3_agent_subscription_count(e3_agent_handle_t *agent)
Total number of active subscriptions tracked by the agent.
Definition c_api.cpp:423
e3_error_t e3_agent_set_dapp_report_handler(e3_agent_handle_t *agent, e3_dapp_report_cb handler)
Set callback for incoming dApp reports (dApp -> RAN).
Definition c_api.cpp:278
e3_error_t(* e3_sm_start_cb)(void *sm_context)
Definition c_api.h:28
void(* e3_sm_stop_cb)(void *sm_context)
Definition c_api.h:29
e3_agent_handle_t * e3_agent_create_default()
Create/destroy an E3Agent handle.
Definition c_api.cpp:186
e3_error_t e3_agent_send_message_ack(e3_agent_handle_t *agent, uint32_t request_id, int response_code)
Send a message acknowledgment (e.g. ack a control/request from dApp).
Definition c_api.cpp:408
int e3_agent_is_running(e3_agent_handle_t *agent)
Query whether the agent is currently running.
Definition c_api.cpp:273
uint32_t * e3_agent_get_registered_dapps(e3_agent_handle_t *agent, size_t *out_len)
Return a newly-allocated array of registered dApp IDs.
Definition c_api.cpp:321
e3_error_t e3_service_model_emit_message_ack(e3_service_model_handle_t *sm, uint32_t request_id, int response_code)
Emit a message acknowledgment from a ServiceModel.
Definition c_api.cpp:170
int(* e3_sm_is_running_cb)(void *sm_context)
Definition c_api.h:30
int e3_agent_get_state(e3_agent_handle_t *agent)
Get the agent state as an integer matching libe3::AgentState.
Definition c_api.cpp:268
e3_error_t e3_agent_start(e3_agent_handle_t *agent)
Start the agent processing threads and accept dApp connections.
Definition c_api.cpp:232
void e3_service_model_destroy(e3_service_model_handle_t *sm)
Destroy a C-backed ServiceModel handle.
Definition c_api.cpp:136
e3_agent_handle_t * e3_agent_create_with_config(const e3_config_t *config)
Create a new E3Agent with the given configuration.
Definition c_api.cpp:190
e3_error_t e3_agent_send_indication(e3_agent_handle_t *agent, uint32_t dapp_id, uint32_t ran_function_id, const uint8_t *data, size_t data_len)
Send an indication message to a specific dApp.
Definition c_api.cpp:380
e3_error_t e3_agent_init(e3_agent_handle_t *agent)
Initialize the agent.
Definition c_api.cpp:227
uint32_t * e3_agent_get_active_ran_functions(e3_agent_handle_t *agent, size_t *out_len)
Return a newly-allocated array of RAN function IDs that currently have at least one subscriber (RAN r...
Definition c_api.cpp:339
uint32_t * e3_agent_get_dapp_subscriptions(e3_agent_handle_t *agent, uint32_t dapp_id, size_t *out_len)
Return a newly-allocated array of RAN function IDs subscribed by a dApp.
Definition c_api.cpp:327
struct e3_service_model_handle_s e3_service_model_handle_t
Definition c_api.h:22
e3_error_t(* e3_sm_init_cb)(void *sm_context)
Definition c_api.h:26
uint32_t * e3_agent_get_subscription_control_ids(e3_agent_handle_t *agent, uint32_t dapp_id, uint32_t ran_function_id, size_t *out_len)
Get the control IDs a dApp requested for a RAN function.
Definition c_api.cpp:365
e3_error_t e3_service_model_emit_indication(e3_service_model_handle_t *sm, uint32_t dapp_id, uint32_t ran_function_id, const uint8_t *data, size_t data_len)
Emit an indication message from a ServiceModel to the outbound queue.
Definition c_api.cpp:143
size_t e3_agent_dapp_count(e3_agent_handle_t *agent)
Number of registered dApps known to the agent.
Definition c_api.cpp:418
uint32_t * e3_agent_get_subscription_telemetry_ids(e3_agent_handle_t *agent, uint32_t dapp_id, uint32_t ran_function_id, size_t *out_len)
Get the telemetry IDs a dApp requested for a RAN function.
Definition c_api.cpp:354
uint32_t * e3_agent_get_available_ran_functions(e3_agent_handle_t *agent, size_t *out_len)
Return a newly-allocated array of available RAN function IDs.
Definition c_api.cpp:315
e3_error_t e3_agent_send_xapp_control(e3_agent_handle_t *agent, uint32_t dapp_id, uint32_t ran_function_id, const uint8_t *control_data, size_t control_data_len, uint32_t sequence_id)
Send an xApp control action to a specific dApp (e.g. from E2/SM).
Definition c_api.cpp:393
e3_error_t e3_agent_set_dapp_status_changed_handler(e3_agent_handle_t *agent, e3_dapp_status_changed_cb handler)
Set callback for dApp status changes.
Definition c_api.cpp:437
libe3 error codes - shared C/C++ definitions
int e3_error_t
C error type alias.
Descriptor describing a ServiceModel implemented in C.
Definition c_api.h:82
const uint32_t * control_ids
Definition c_api.h:90
e3_sm_stop_cb sm_stop
Definition c_api.h:104
const uint8_t * ran_function_data
Definition c_api.h:97
const uint32_t * telemetry_ids
Definition c_api.h:87
const char * name
Definition c_api.h:83
e3_sm_start_cb sm_start
Definition c_api.h:103
e3_sm_init_cb sm_init
Definition c_api.h:101
e3_sm_is_running_cb sm_is_running
Definition c_api.h:105
size_t ran_function_data_len
Definition c_api.h:98
e3_sm_process_control_cb sm_process_control
Definition c_api.h:106
uint32_t ran_function_id
Definition c_api.h:85
e3_sm_destroy_cb sm_destroy
Definition c_api.h:102
Configuration for creating an E3Agent from C.
Definition c_api.h:168
int encoding
Definition c_api.h:178
int log_level
Definition c_api.h:180
uint16_t subscriber_port
Definition c_api.h:173
int pin_io_threads
Definition c_api.h:183
const char * setup_endpoint
Definition c_api.h:175
int link_layer
Definition c_api.h:170
const char * log_path
Definition c_api.h:181
size_t io_threads
Definition c_api.h:179
uint16_t setup_port
Definition c_api.h:172
uint16_t publisher_port
Definition c_api.h:174
int io_thread_affinity
Definition c_api.h:184
const char * ran_identifier
Definition c_api.h:169
const char * subscriber_endpoint
Definition c_api.h:176
int transport_layer
Definition c_api.h:171
const char * publisher_endpoint
Definition c_api.h:177
uint32_t ran_function_id() const override
Get RAN function ID for this SM.
Definition c_api.cpp:77