RobustOS SDK System, Messaging, and Event API Reference

Use RobustOS system, messaging, and event APIs

Use the RobustOS C APIs to write logs, access device environment values, exchange messages with local services, and subscribe to system events. This reference includes function results, string ownership, and event names to check when integrating your application.

Applies to: C applications built with a matching RobustOS SDK and deployed to the exact device model and firmware for that SDK target. API availability and declarations must match the headers supplied with your SDK. This reference does not establish compatibility with RobustOS Pro or with every RobustOS release.

The SDK provides librouter for these platform functions. Target headers and libraries are under staging_dir/target-<platform>/usr/ in the SDK workspace. The event example uses "librouter.h" and "event.h"; the latter is the libevent header. Check the selected SDK's headers and sample package for the complete includes and link settings before compiling. The snippets below explain individual operations; they are not standalone applications or verified build recipes.

Choose the right API family

You need to work withUse
Application log messageslog_*
Configured values and configuration listsuci_*
Live status values and status listsusi_*
RobustOS environment name/value pairsrenv_*
Messages between local processesrmsg_*
Subscriptions and reports through the event serviceevent_*, after initializing rmsg_*

UCI configuration expresses what a service should do. USI status describes what it is doing or what it has observed. Publishing a USI value does not replace changing the associated configuration. Use the dedicated UCI configuration API reference and USI status API reference for their full function declarations and workflows.

For calls that accept a tag, use the exact configuration or status tag discovered on the target device. A list member can be addressed as category.list[1].member. List IDs begin at 1; do not convert them into zero-based C array indexes. An absent entry is possible even when a higher ID exists.

Understand types, results and ownership

SDK types and constants

Use the SDK headers rather than adding these typedefs to your own source. The following declarations identify the types used by this API set; in particular, the intptr_t declaration must not be treated as a portable declaration for a host-side 64-bit program.

typedef signed char        int8_t;
typedef short int          int16_t;
typedef int                int32_t;
typedef long long int      int64_t;
typedef unsigned char      uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long int uint64_t;
typedef int                intptr_t;
typedef int                status_t;
typedef unsigned int       bool_t;

#define TRUE  1
#define FALSE 0
#define ERROR -1
#define OK    0

#ifndef NULL
#define NULL ((void *)0)
#endif

A function returning status_t normally reports OK for success and ERROR for an error, where its entry below specifies that contract. A bool_t predicate returns TRUE or FALSE for its stated test. Do not assume that every predicate reports a separate error code.

An integer getter that returns 0 on error cannot distinguish a valid zero from an error by its return value alone. A string getter returning NULL indicates an error under the documented contract; it does not by itself distinguish a missing tag from other failures. A returned empty string is different from a NULL pointer.

Who releases returned strings?

CallHandling after a successful call
uci_get, renv_getDo not call free() on the returned value. The API manages it.
usi_get, usi_list_get, rmsg_getThe caller releases each returned allocation with free().
uci_list_getReturns const char *; ownership and lifetime need confirmation in the SDK header. Do not infer them from another getter.
rmsg_recv outputs msg and fromBuffer ownership and lifetime need confirmation in the SDK header/sample. The rmsg_get ownership rule does not specify how these two outputs are released.

Check for NULL before reading a returned string. Keep cleanup on all exit paths, including messages you decide to ignore. No lifetime, thread-safety, or re-entrancy guarantee is implied for a borrowed pointer.

Write application logs

The logger helpers send messages to syslog. These are call forms, not complete C prototypes; their return types and macro/function declarations come from your SDK header.

Call formUse
log_open(n)Set the identity prepended to messages, typically the program name. Opening explicitly is optional; when needed, syslog opens automatically with a default NULL identity.
log_close()Close the descriptor used to write to the system logger. Explicit closing is optional.
log_debug(fmt, ...)Write a debug message.
log_info(fmt, ...)Write an information message.
log_notice(fmt, ...)Write a notice message.
log_warn(fmt, ...)Write a warning message.
log_error(fmt, ...)Write an error message.

No return value is specified for these seven helpers. Use messages to record an operation and its result, then inspect them using the debugging workflow. A successful build does not prove that a message is visible under the device's current logging settings.

Use RobustOS environment values

RobustOS environment values are accessed by name through renv_*. These calls are distinct from reading a shell process's ordinary environment with a standard C library function.

status_t renv_set(const char *name, const char *value);
status_t renv_printf(const char *name, const char *fmt, ...);
const char *renv_get(const char *name);
int32_t renv_get_int(const char *name);
uint32_t renv_get_uint(const char *name);
status_t renv_del(const char *name);
bool_t renv_match(const char *name, const char *value);
FunctionInputs and result
renv_setAdd or change the pair identified by name, using string value. Return OK or ERROR.
renv_printfSet the named value using printf-style fmt and its arguments. Return OK or ERROR.
renv_getReturn the named value pointer, or NULL on error. Do not free the pointer.
renv_get_intReturn the signed integer value, or 0 on error.
renv_get_uintReturn the unsigned integer value, or 0 on error.
renv_delDelete the named pair. Return OK or ERROR.
renv_matchCompare the named value with string value. Return TRUE for a match or FALSE otherwise.

For a device shell, the corresponding command forms are:

renv
renv get <name>
renv set <name> <value>
renv del <name>

With no command, renv prints the current RobustOS environment. Replace the angle-bracket inputs before running a command. Use only names whose purpose and valid values are established for your device. Read-only inspection does not authorize changing a system-owned value.

The status example uses renv_get_int("cellular_current_sim") to choose an entry in cellular.status. That example does not establish a universal relationship between a SIM index, modem index and list ID on every device. Check the actual status layout before using the value as an index. Persistence across restart, allowed variable names and access restrictions need confirmation for the selected release.

Exchange messages with another local process

The IPC (inter-process communication) API uses a UNIX-domain socket. Initialize it before sending messages, check the socket descriptor, use the message format expected by the destination service, then close the interface when finished.

int rmsg_init(const char *sock_name);
status_t rmsg_close(void);
status_t rmsg_recv(char **msg, char **from);
char *rmsg_get(const char *key);
FunctionInputs and result
rmsg_initsock_name is a socket name without a path. Return the socket descriptor on success or -1 on error. Call it before rmsg_send and before using event-service operations.
rmsg_closeClose the messaging interface when no further messages are needed. Return OK or ERROR.
rmsg_recvReceive a message using the msg and from pointer arguments. Return OK or ERROR. Check the release header for buffer ownership, blocking behavior and the lifetime of the received-message context.
rmsg_getObtain the value for a message key. Return an allocated value pointer or NULL on error; the caller frees the result. The event workflow calls this after a successful rmsg_recv.

The send call is given in abbreviated form:

status_t rmsg_send(dst, msgs, ...)

dst is the destination socket name. msgs represents message key/value pairs. The result is OK or ERROR. This is not a complete typed C declaration. Before implementing a new IPC message, check the release header and destination-service example for the actual parameter types, argument termination and message framing. Do not add or omit a sentinel by guesswork.

The email example uses destination emaild and the keys cmd, addresses, and content, with command value send. Those fields describe that service request; they are not a generic command language for every RobustOS service. See Use hardware and system services for its configuration prerequisites.

A successful send means the send call succeeded. Confirm the destination's observable result separately; do not treat it as a delivery or operation-completion acknowledgement unless the service defines that behavior.

Subscribe to and report events

Connect your subscriber to the event service

The event API uses the messaging interface initialized by rmsg_init():

  1. Choose a socket name without a path, initialize messaging and stop if the descriptor is -1.
  2. Initialize the application's libevent loop and register the messaging descriptor for reading. The example uses EV_READ | EV_PERSIST so that the callback remains registered.
  3. Subscribe to the required event names and check each subscription result.
  4. Dispatch the event loop. In the read callback, call rmsg_recv() and continue only when it returns OK.
  5. Read the message's cmd field. Process event-report fields only when it is "report".
  6. Read event, desc and date, check pointers before use, and release the allocations returned by rmsg_get() on every path.
  7. On a normal application exit, unsubscribe from events and close the messaging interface. Follow the SDK's contract for the receive buffers and the libevent objects.

The provided subscriber example uses event_init, event_set, event_add, event_dispatch and a callback with signature void event_msg_proc(int sock, short ev, void *arg). Use the libevent version and example supplied with the target SDK; this reference does not substitute a different libevent API generation.

If you use event_unsubscribe_all() before making new subscriptions, confirm its scope in your release before treating it as a startup reset. Provide a socket name without a path; do not pass argv[0] without checking whether the invocation includes a path.

Event API reference

status_t event_subscribe(const char *event);
status_t event_unsubscribe_all(void);
status_t event_report(const char *event, const char *data);
status_t event_report_with_formatted_data(const char *event,
                                         const char *fmt, ...);
status_t event_report_full(const char *from, const char *event,
                          const char *data);
status_t event_report_full_with_formatted_data(const char *from,
                                              const char *event,
                                              const char *fmt, ...);

All six calls return OK or ERROR.

FunctionInputs and purpose
event_subscribeSubscribe to the named event through the event service. Initialize messaging first.
event_unsubscribe_allUnsubscribe from all events. Call before exiting after subscriptions; confirm the precise subscription scope in the release implementation.
event_reportReport event with extra string data. Initialize messaging first.
event_report_with_formatted_dataReport event with extra data formed from printf-style fmt and its arguments.
event_report_fullReport event with data and explicit from; from is the same name used in rmsg_init. The declaration accepts a data string, not a format and variadic arguments.
event_report_full_with_formatted_dataSupply explicit from and format the report's data from fmt and its arguments.

Important: Check the release header before using either event_report_full variant. Use the fixed-data and formatted-data declarations exactly as provided by that header. Do not pass formatting arguments to the fixed-data declaration. Event-service acceptance of a report also does not prove that a particular subscriber has handled it.

Handle report fields without losing allocations

This fragment replaces only the field-decoding portion of an event callback. Call it after rmsg_recv() has returned OK. It does not implement the callback's receive-buffer cleanup or the event-loop lifecycle, because those ownership details must be checked against the selected SDK.

static void handle_received_report_fields(void)
{
    char *cmd = NULL;
    char *event_name = NULL;
    char *description = NULL;
    char *date = NULL;

    cmd = rmsg_get("cmd");
    if (cmd == NULL || strcmp(cmd, "report") != 0) {
        goto cleanup;
    }

    event_name = rmsg_get("event");
    description = rmsg_get("desc");
    date = rmsg_get("date");

    if (event_name == NULL) {
        goto cleanup;
    }

    log_info("receive event %s, desc = %s, date = %s",
             event_name,
             description != NULL ? description : "",
             date != NULL ? date : "");

cleanup:
    free(cmd);
    free(event_name);
    free(description);
    free(date);
}

The fragment uses standard string and allocation functions in addition to librouter; include their declarations when integrating it. Add application behavior after checking the event name. Missing optional fields are logged as empty strings here; that is an example handling choice, not an event-service guarantee about which fields are optional.

Event names to match exactly

Use only events provided by the selected device and its enabled services. The catalogue is a reference for known event identifiers, not a guarantee that all hardware or services exist on every target. No event payload schema, delivery order, replay behavior or delivery guarantee is defined by these names alone.

System and configuration

EventMeaning
system_startupThe system has started.
system_rebootThe system is going to reboot.
system_time_updatedSystem time has been updated.
system_login_successA system login succeeded.
system_login_failA system login failed.
config_changedConfiguration has changed.

Cellular service and links

EventMeaning
cellular_data_stats_clearCellular data statistics were cleared.
cellular_data_traffic_overflowCellular data traffic reached its threshold.
cellular_network_type_changedThe cellular network type changed.
poor_signal_qualitySignal quality is poor.
link_switchThe system is going to switch links.
wan_up, wan_downThe WAN data connection came up or went down.
wlan_up, wlan_downThe WLAN data connection came up or went down.
wwan_up, wwan_downThe WWAN data connection came up or went down.
lan_port_up, lan_port_downA LAN port link came up or went down.

VPN, position, USB and dynamic DNS

EventMeaning
ipsec_up, ipsec_downAn IPsec tunnel came up or went down.
openvpn_up, openvpn_downAn OpenVPN tunnel came up or went down.
robustvpn_up, robustvpn_downA RobustVPN tunnel came up or went down.
gps_up, gps_downA GPS fix succeeded or failed.
usb_connected, usb_removedA USB device was inserted or removed.
ddns_update_success, ddns_update_failA dynamic DNS update succeeded or failed.

SMS

EventMeaning
sms_receivedA new message was received.
sms_sentA message was sent.
sms_cmd_executedA command in a message was executed.

Digital inputs

Event identifiersMeaning and applicability
di1_on, di1_off, di1_counter_overflowDI1 enabled, disabled, or its counter reached the threshold. Check the device's definition of the electrical state.
di2_on, di2_off, di2_counter_overflowDI2-named events. Confirm the channel mapping on the selected device before use.
di3_on, di3_off, di3_counter_overflowDI3-named events. Confirm the channel mapping on the selected device before use.
di4_on, di4_off, di4_counter_overflowDI4-named events. Confirm the channel mapping on the selected device before use.

Check DI2-DI4 channel mapping against the target's event sample and a controlled input change on the development device. The presence of an event name in this list does not establish that the corresponding channel is available on your hardware.

Analog input

EventMeaning
ai1_voltage_lowVoltage reaches the minimum threshold.
ai1_voltage_highVoltage reaches the maximum threshold.
ai1_current_lowCurrent reaches the minimum threshold.
ai1_current_highCurrent reaches the maximum threshold.
ai1_recoveryVoltage or current returns to normal.

Threshold events indicate a condition change; they are not a replacement for reading a precise analog value. See Use hardware and system services for device-specific input access.

Check the result of your integration

For a read path, confirm that the exact tag exists on the device, handle its empty/error cases and compare one retrieved value with the corresponding device view. For a write path, check the function result and then the observable configuration, status or destination-service outcome. For a subscriber, capture the received event name and time when a permitted development action triggers it; do not manufacture a system event to stand in for an actual device action.

Before release, check these failure points:

  • A compile error on a declaration: compare the target SDK header and library with the function spelling and argument types used here.
  • A zero integer or FALSE predicate: use the function's exact contract; those results may be insufficient to diagnose an error.
  • A crash or increasing memory use: check NULL handling, borrowed versus allocated strings, and cleanup paths for ignored messages.
  • A list read failure: confirm one-based IDs, the list tag, empty entries and the selected release's maximum-entry contract.
  • No received events: check successful socket initialization, the exact event name, successful subscriptions, event-loop registration and whether the relevant device service can emit that event.

Keep build and device results separate. Compile the integration against your selected SDK, then exercise each API path on the designated device before accepting the application for release.