Skip to content

API Reference (Telemetry-Relevant Subset)

This section summarizes the parts of the Coldwave and flake::Service APIs that are most relevant for telemetry. The public Coldwave surface is split across two headers: coldwave.h (core lifecycle, OTA, power, signing, optional Wi-Fi commissioning when libcoldwave is built with router support) and coldwave_ble_config.h (optional BLE-bound local config service). Everything not declared in those two headers is internal and may change without notice.

Result codes (coldwave_result_t)

All Coldwave entry points return a signed integer compatible with libflake's E_OK / E_FAILED constants. CW_OK is 0, so existing if (rc != E_OK) checks remain valid; new code should prefer the CW_* names.

CodeValueMeaning
CW_OK0Success.
CW_ERR_FAILED-1Generic failure (compatible with E_FAILED).
CW_ERR_NOT_INITIALIZED-10coldwave_init() has not completed successfully.
CW_ERR_ALREADY_ATTACHED-11coldwave_backend_attach() called while already attached.
CW_ERR_NOT_ATTACHED-12Operation requires an attached backend.
CW_ERR_INVALID_ARG-13A required parameter was null or out of range.
CW_ERR_NO_BACKEND-14Backend FQDN missing or could not be resolved.
CW_ERR_NO_NETWORK_IF-15No suitable network interface for the backend.
CW_ERR_TRANSPORT-16Wire/transport setup failed.
CW_ERR_NOT_SUPPORTED-17Feature compiled out (e.g. router disabled, BLE config off-target).

Initialization parameters

coldwave_init_t

FieldTypeDescription
node_typecoldwave_node_tcwClient (endpoint) or cwRouter (gateway). Telemetry devices use cwClient.
app_semverconst char*SemVer string of the currently running firmware. Surfaced as the installed-version FU property for slot 0.
device_idconst char*Globally unique device identifier (IMEI, serial, …). Required.
product_idconst char*4-character alphanumeric product identifier.
hw_idconst char*Hardware / SoC identifier used by OTA to pick the right image.
backendcoldwave_backend_tBackend connection parameters (see below). Mandatory for cwClient.
net_device_handleintOpen handle for the primary network device (open("modem0"), open("wlan0"), open("eth0")). -1 if none.
net_device_typecoldwave_net_device_type_tcwNetNone, cwNetEthernet, cwNetWiFi or cwNetLte. Drives MAC/LTE readout.
opt.clientcoldwave_client_options_tClient-only options (see below). Used when node_type == cwClient.
opt.routercoldwave_router_options_tRouter-only options (see below). Used when node_type == cwRouter.

Use COLDWAVE_INIT_DEFAULT as the initializer:

cpp
coldwave_init_t cw_init = COLDWAVE_INIT_DEFAULT;

coldwave_backend_t

FieldTypeDescription
fqdnconst char*Fully-qualified backend host name. Required for cwClient.
ca_certunsigned char*DER-encoded CA certificate. nullptr falls back to unencrypted UDP (PTP).
ca_cert_lenunsignedByte length of ca_cert.

coldwave_client_options_t

FieldTypeDescription
monthly_data_limit_bytesunsignedIf non-zero, monthly volume is tracked for reporting (see coldwave_get_remaining_budget()); does not throttle syncing.
remaining_data_budget_bytesunsignedIf non-zero, the budget tracker starts with this much budget left this month.
desired_sync_interval_sintDeprecated, ignored — syncs are no longer paced on-device; rate limiting is enforced by the backend.

coldwave_router_options_t

FieldTypeDescription
no_local_tlsintIf non-zero, local client connections are unencrypted.
local_tcp_portuint16_tTCP port for local clients. 0 uses the default (9986/9987).
local_network_interfaceconst char*Name of the interface to bind to; nullptr binds to all interfaces.
auth_callbackcoldwave_auth_callback_tCalled on every new local connection. nullptr disables authentication.
auto_update_disabledintIf non-zero, the backend will not start OTA when new versions are available.
max_clientsintMaximum number of concurrent local clients. 0 means unlimited.

coldwave_auth_callback_t has signature int (*)(const flake::PropArray& rops) and must return CW_OK to accept the client.

Coldwave core C API (coldwave.h)

Lifecycle

FunctionDescription
int coldwave_init(const coldwave_init_t* init, const char* srv_uuid, flake::Service** srv)Initialize Coldwave. For cwClient, creates the wire from init->backend and calls flakeInitialize(); no traffic until coldwave_backend_attach(). For cwRouter, brings up the local server. If *srv is null a default ServiceWrapper is allocated.
int coldwave_register_service(const char* srv_uuid, flake::Service** srv, const PropArray& initial_props = PropArray())Register an additional service on the same node.
int coldwave_backend_attach(void)Attach to the configured backend and start syncing. Backend FQDN/CA come from coldwave_init_t::backend. Non-blocking — the connection is established asynchronously.
int coldwave_backend_detach(void)Disconnect from the backend but keep the flake CoreWorker and the connection object alive. coldwave_backend_attach() can be called again without re-initializing.
bool coldwave_backend_attached(void)Whether the Coldwave backend is currently attached and online.
int coldwave_suspend(void)Suspend the connection management thread. Disconnects from the backend but keeps the CoreWorker and connection object alive.
int coldwave_resume(void)Resume after coldwave_suspend(). If the user previously attached, reconnection is triggered automatically.
int coldwave_uninit(void)Tear down Coldwave. Disconnects the backend (if attached), stops internal threads, uninitializes flake and frees all owned resources.

Data budget (client only)

FunctionDescription
unsigned coldwave_get_remaining_budget(void)Remaining monthly data budget in bytes. Returns 0 if not initialized or no budget configured.
void coldwave_reset_budget(void)Reset the monthly budget manager.

OTA

FunctionDescription
int coldwave_ota_autoupdate_enable(bool e)Enable or disable automatic OTA updates.
bool coldwave_ota_autoupdate_enabled(void)Whether OTA autoupdate is currently enabled.
int coldwave_register_hw_ota_target(const cw_hw_ota_target_t* t)Register a per-slot OTA target so libcoldwave can observe the lifecycle (DOWNLOADING/INSTALLING/SUCCESS/FAILED) on the OS-side OTA flow. Slot 0 is reserved for libcoldwave's own SW-OTA.

cw_hw_ota_target_t fields:

FieldTypeDescription
slotuint8_t1..(COLDWAVE_HW_SLOTS_MAX-1). Slot 0 is reserved.
ota_target_idintValue used in ota_t::target / ota_register_target_handler.
ctxvoid*Opaque context forwarded to the integrator callbacks.
on_begincw_hw_ota_begin_tOptional. Called when the OS-side OTA flow starts the target.
on_appendcw_hw_ota_append_tRequired. Called for every chunk of bytes.
on_finalizecw_hw_ota_finalize_tOptional. Called on successful completion.
on_abortcw_hw_ota_abort_tOptional. Called on abort/failure.

Power & temperature push

For values that have no portable platform binding (battery rail, on-die temperature, ...), the integrator samples them and pushes them via:

cpp
int coldwave_set_power_info(const cw_power_info_t* info);

cw_power_info_t fields:

FieldTypeDescription
fieldsuint32_tOR'd bitmask: CW_POWER_INFO_BATTERY_MV, CW_POWER_INFO_BATTERY_PCT, CW_POWER_INFO_TEMPERATURE. Only fields whose bit is set are read.
battery_mvuint16_tBattery rail voltage in millivolts. Use UINT16_MAX (with the bit set) to mark the value as unknown.
battery_pctuint8_tEstimated battery state-of-charge in percent (0–100).
temperature_c10int16_tOn-die / ambient temperature in deci-Celsius (°C × 10).

libcoldwave caches the values and the connection loop publishes them at the next sync.

Signing

cpp
int coldwave_sign  (const char* message, size_t message_len,
                    const char signature_buf[COLDWAVE_SIGNATURE_LEN]);
int coldwave_verify(const char* message, size_t message_len,
                    const char signature_buf[COLDWAVE_SIGNATURE_LEN]);

Sign / verify a buffer using the device's key. COLDWAVE_SIGNATURE_LEN is the required output buffer size (64 bytes for the portable build; on __COLDWAVE_OS__ / __CXOS__ builds it is PSA_ECDSA_SIGNATURE_SIZE(256)).

Wi-Fi commissioning (router builds only)

These entry points are only available when libcoldwave is built with router support (COLDWAVE_HAS_ROUTER). On other builds they are not declared at all — guard call sites with #if COLDWAVE_HAS_ROUTER.

FunctionDescription
int coldwave_start_ap_wifi_commissioning(int wifi_dev, const char* ssid, const char* pass, uint32_t timeout_ms, wifi_commissioning_data_callback_t cb)Start AP-mode Wi-Fi commissioning.
int coldwave_start_ble_wifi_commissioning(int wifi_dev, int ble_dev, const char* ble_name, uint32_t timeout_ms, wifi_commissioning_data_callback_t cb)Start BLE-mediated Wi-Fi commissioning.
void coldwave_end_wifi_commissioning(void)Stop the in-progress commissioning flow.

Optional BLE-bound local config service (coldwave_ble_config.h)

A cwClient can additionally expose a single integrator-defined config service on a local Flake router that is bound to a BLE wire. The cloud-facing client connection is unaffected; the two stacks run in parallel.

This feature requires libcoldwave to be built with __COLDWAVE_OS__ / __CXOS__ (OS-side BLE driver + libflake router). On other targets both entry points return CW_ERR_NOT_SUPPORTED.

Functions

FunctionDescription
int coldwave_start_ble_config_service(const cw_ble_config_init_t* init)Open a local router on a BLE wire and register a single config service on it. Spawns the app thread, which installs handlers before BLE advertising starts.
void coldwave_stop_ble_config_service(void)Idempotent. Stops advertising, signals the app thread to exit, waits for it to join, then tears down the local router. Safe from inside a service handler.
int coldwave_ble_config_should_stop(void)True while a stop has been requested but the local router has not yet been torn down. App threads poll this and return when it flips to true.

cw_ble_config_init_t

FieldTypeDescription
srv_uuidconst char*UUID of the local config service.
ble_uart_devintopen("uart0") result — caller-owned.
ble_local_nameconst char*BLE advertised name, max 22 chars. nullptr leaves it unchanged.
auto_reconnectintNon-zero toggles BLE_IOCTL_AUTO_RECONNECT.
auth_callbackcoldwave_auth_callback_tOptional. When set, the local router runs with authentication; invoked on every new client connection.
user_ctxvoid*Forwarded as-is to thread_fn and on_stopped.
thread_fncw_ble_config_thread_fn_tRequired. Registers Property/customMessage handlers on srv and drives the update loop until coldwave_ble_config_should_stop() returns true.
thread_stack_sizeuint32_t0 = libcoldwave default (4096).
thread_nameconst char*nullptr = "cw_ble_cfg".
on_stoppedvoid (*)(void* user_ctx)Optional. Called after teardown finishes.

Lifecycle inside coldwave_start_ble_config_service():

  1. flakeInitializeWithRouter() (or …AndAuth() if auth_callback is set).
  2. A fresh ServiceWrapper is registered under init->srv_uuid.
  3. The app thread is started — its first job is handler registration.
  4. The BLE local name is set, the BLE server wire is added, advertising starts, and auto_reconnect is applied.

Step 3 runs before step 4 so a peer cannot connect to a service whose handlers have not been installed yet.

flake::Service (excerpt)

All methods are declared in <flake/Service.h>.

Core methods for telemetry:

MemberDescription
template<uint32_t PropTag, typename T> int set(T value)Set the value of a property identified by PropTag. Returns E_OK on success, E_REFUSED if the value cannot be converted or if called from within a forbidden callback context.
template<uint32_t PropTag> PropType<PropTag> get(PropType<PropTag> defval = ...)Get the value of a property, or defval if not available.
template<uint32_t PropTag> int on(PropCallback<PropTag> cb)Register a property callback for a tag (called when the property is written by the backend).
template<uint32_t PropTag> int on(PropCallback<PropTag & ~TAG_ACTIONABLE> cb, PropType<PropTag> min, PropType<PropTag> max)Register a property callback with range validation for actionable properties.
template<uint32_t PropTag> int onRead(PropCallBackStreamRead cb)Register stream read callback for a stream property.
template<uint32_t PropTag> int onWrite(PropCallBackStreamWrite cb)Register stream write callback for a stream property.
template<uint32_t PropTag> int onOpenClose(PropCallBackStreamOpenClose cb)Register stream open/close callback.
int openProperty(const uint32_t propTag, Stream** stream)Open a stream for the given property tag (for large or streaming telemetry).
int sync(int timeout_ms = FLAKE_DEFAULT_TIMEOUT_MS)Exchange pending property updates and messages with the backend.
void defer() / int syncDeferred(unsigned timeout_ms, bool block) / bool hasDeferred()Low-level control of deferred sync batches.
unsigned pendingBytes()Get the number of pending bytes waiting to be sent.
void reset()Reset the service state.