Appearance
Initializing Coldwave and the Service
Fill coldwave_init_t
Use the Coldwave init structure to configure your device identity and client options:
cpp
#include <coldwave/coldwave.h>
#include <Service.h>
static flake::Service* service = nullptr;
// Example: ~6.5 MB per month for telemetry
#define MONTHLY_BUDGET static_cast<unsigned>(6.5 * 1024 * 1024)
void coldwave_init_app(const char* device_id_imei)
{
coldwave_init_t cw_init = COLDWAVE_INIT_DEFAULT; // default initializer
cw_init.app_semver = APP_VERSION_STR; // your firmware SemVer
cw_init.device_id = device_id_imei; // globally unique device ID (e.g. IMEI)
cw_init.product_id = "YD42"; // optional: product identifier
cw_init.hw_id = "default"; // SoC / hardware ID for updates
// Backend is mandatory for cwClient and must be set BEFORE coldwave_init():
cw_init.backend.fqdn = COLDWAVE_BACKEND_URL;
cw_init.backend.ca_cert = backend_ca; // DER bytes
cw_init.backend.ca_cert_len = backend_ca_len;
// Primary network interface used to reach the backend:
cw_init.net_device_handle = modem_fd; // open("modem0", ...)
cw_init.net_device_type = cwNetLte; // drives MAC + LTE pull-path
cw_init.opt.client.monthly_data_limit_bytes = MONTHLY_BUDGET;
cw_init.opt.client.remaining_data_budget_bytes = MONTHLY_BUDGET;
// UUID of your generated service (from your Flake data model)
const char* SERVICE_UUID = YD42_SRV_UUID;
int rc = coldwave_init(&cw_init, SERVICE_UUID, &service);
if (rc != CW_OK) {
// handle error
}
}Key points:
device_idmust be unique per device (IMEI or similar).app_semver,product_idandhw_idare used for version tracking and OTA.backend.fqdnis mandatory forcwClient: the wire is created andflakeInitialize()is called insidecoldwave_init(). No network traffic happens yet — it is triggered bycoldwave_backend_attach().monthly_data_limit_bytesandremaining_data_budget_bytestrack your monthly data usage for reporting andcoldwave_get_remaining_budget(); they do not change sync behavior — rate limits are enforced by the backend.servicewill point to your device’sflake::Serviceinstance aftercoldwave_init()succeeds.
Persisting and restoring the data budget (optional)
You can persist the remaining data budget across reboots (e.g. in RTC RAM or flash) and feed it back into Coldwave before calling coldwave_init():
cpp
uint32_t remaining_budget = MONTHLY_BUDGET;
// Load last remaining budget from non-volatile memory:
uint32_t persisted = load_remaining_budget_from_nv();
if (persisted > 0U && persisted < MONTHLY_BUDGET) {
remaining_budget = persisted;
}
cw_init.opt.client.remaining_data_budget_bytes = remaining_budget;Later, while attached, you can periodically refresh and persist the budget using coldwave_get_remaining_budget():
cpp
if (coldwave_backend_attached()) {
remaining_budget = coldwave_get_remaining_budget();
save_remaining_budget_to_nv(remaining_budget);
}This pattern keeps your usage accounting consistent across device restarts.