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.
| You need to work with | Use |
|---|---|
| Application log messages | log_* |
| Configured values and configuration lists | uci_* |
| Live status values and status lists | usi_* |
| RobustOS environment name/value pairs | renv_* |
| Messages between local processes | rmsg_* |
| Subscriptions and reports through the event service | event_*, 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.
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.
| Call | Handling after a successful call |
|---|---|
uci_get, renv_get | Do not call free() on the returned value. The API manages it. |
usi_get, usi_list_get, rmsg_get | The caller releases each returned allocation with free(). |
uci_list_get | Returns const char *; ownership and lifetime need confirmation in the SDK header. Do not infer them from another getter. |
rmsg_recv outputs msg and from | Buffer 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.
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 form | Use |
|---|---|
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.
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);
| Function | Inputs and result |
|---|---|
renv_set | Add or change the pair identified by name, using string value. Return OK or ERROR. |
renv_printf | Set the named value using printf-style fmt and its arguments. Return OK or ERROR. |
renv_get | Return the named value pointer, or NULL on error. Do not free the pointer. |
renv_get_int | Return the signed integer value, or 0 on error. |
renv_get_uint | Return the unsigned integer value, or 0 on error. |
renv_del | Delete the named pair. Return OK or ERROR. |
renv_match | Compare 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.
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);
| Function | Inputs and result |
|---|---|
rmsg_init | sock_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_close | Close the messaging interface when no further messages are needed. Return OK or ERROR. |
rmsg_recv | Receive 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_get | Obtain 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.
The event API uses the messaging interface initialized by rmsg_init():
-1.EV_READ | EV_PERSIST so that the callback remains registered.rmsg_recv() and continue only when it returns OK.cmd field. Process event-report fields only when it is "report".event, desc and date, check pointers before use, and release the allocations returned by rmsg_get() on every path.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.
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.
| Function | Inputs and purpose |
|---|---|
event_subscribe | Subscribe to the named event through the event service. Initialize messaging first. |
event_unsubscribe_all | Unsubscribe from all events. Call before exiting after subscriptions; confirm the precise subscription scope in the release implementation. |
event_report | Report event with extra string data. Initialize messaging first. |
event_report_with_formatted_data | Report event with extra data formed from printf-style fmt and its arguments. |
event_report_full | Report 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_data | Supply 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.
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.
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
| Event | Meaning |
|---|---|
system_startup | The system has started. |
system_reboot | The system is going to reboot. |
system_time_updated | System time has been updated. |
system_login_success | A system login succeeded. |
system_login_fail | A system login failed. |
config_changed | Configuration has changed. |
Cellular service and links
| Event | Meaning |
|---|---|
cellular_data_stats_clear | Cellular data statistics were cleared. |
cellular_data_traffic_overflow | Cellular data traffic reached its threshold. |
cellular_network_type_changed | The cellular network type changed. |
poor_signal_quality | Signal quality is poor. |
link_switch | The system is going to switch links. |
wan_up, wan_down | The WAN data connection came up or went down. |
wlan_up, wlan_down | The WLAN data connection came up or went down. |
wwan_up, wwan_down | The WWAN data connection came up or went down. |
lan_port_up, lan_port_down | A LAN port link came up or went down. |
VPN, position, USB and dynamic DNS
| Event | Meaning |
|---|---|
ipsec_up, ipsec_down | An IPsec tunnel came up or went down. |
openvpn_up, openvpn_down | An OpenVPN tunnel came up or went down. |
robustvpn_up, robustvpn_down | A RobustVPN tunnel came up or went down. |
gps_up, gps_down | A GPS fix succeeded or failed. |
usb_connected, usb_removed | A USB device was inserted or removed. |
ddns_update_success, ddns_update_fail | A dynamic DNS update succeeded or failed. |
SMS
| Event | Meaning |
|---|---|
sms_received | A new message was received. |
sms_sent | A message was sent. |
sms_cmd_executed | A command in a message was executed. |
Digital inputs
| Event identifiers | Meaning and applicability |
|---|---|
di1_on, di1_off, di1_counter_overflow | DI1 enabled, disabled, or its counter reached the threshold. Check the device's definition of the electrical state. |
di2_on, di2_off, di2_counter_overflow | DI2-named events. Confirm the channel mapping on the selected device before use. |
di3_on, di3_off, di3_counter_overflow | DI3-named events. Confirm the channel mapping on the selected device before use. |
di4_on, di4_off, di4_counter_overflow | DI4-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
| Event | Meaning |
|---|---|
ai1_voltage_low | Voltage reaches the minimum threshold. |
ai1_voltage_high | Voltage reaches the maximum threshold. |
ai1_current_low | Current reaches the minimum threshold. |
ai1_current_high | Current reaches the maximum threshold. |
ai1_recovery | Voltage 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.
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:
FALSE predicate: use the function's exact contract; those results may be insufficient to diagnose an error.NULL handling, borrowed versus allocated strings, and cleanup paths for ignored messages.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.