InTouch C / C++ device SDK
The C99 core builds into a static library for firmware, RTOS tasks and native Linux processes. A C++11 caller includes the same header with C linkage. The core maintains one mutable burst in caller-owned memory, serializes typed fields directly into that buffer, and hands sealed bytes to your storage hook. It uses standard C formatting and libm. The POSIX example supplies disk persistence and HTTP delivery with libcurl and json-c.
Build and run
Install a C99 compiler, C++11 compiler, make, pkg-config, libcurl development files and json-c development files. Only the example host program needs libcurl/json-c. Linux Debian packages are build-essential pkg-config libcurl4-openssl-dev libjson-c-dev.
make all check
./build/edge-host diagnostics
./build/edge-host sample temperature celsius 4.8
./build/edge-host motion 14 0 0
./build/edge-host sync
Set EDGE_TOKEN in the process environment to the local edge-lab credential. Load it from the ignored repository .env in a trusted shell or secret manager. Set INTOUCH_ORIGIN for another HTTPS service. The default is http://127.0.0.1:8917. The sender accepts plain HTTP only on loopback. Use INTOUCH_SPOOL to select a persistent directory (default .edge-spool, owned by this user with mode 0700). Dedicate one directory per tenant/device/service and preserve it across upgrades. diagnostics reads actual OS CPU count, memory page size and monotonic uptime. sample and motion take caller-provided values. sync drains previously committed batches after a reconnect. Each command exits nonzero if delivery fails and leaves committed files for a later invocation.
# From sdk/c, with the local Docker API running:
python3 tests/roundtrip.py
# Build the standalone Linux sender and run C, C++ and board-adapter checks inside Linux:
docker build -t mappls-intouch-edge:local .
python3 tests/linux_smoke.py
The integration check creates a separate private spool, forces two unsuccessful sends to a closed loopback port, launches a fresh process to drain both files, and verifies each original timestamp, value, trigger and batch ID through the viewer API.
Firmware integration
- Include
include/intouch.hand compilesrc/intouch.cwith C99 support, floating-pointsnprintfand libm. Use the C numeric locale. Reserve a caller-owned arena of 260 bytes to 512 KiB. An 8 KiB arena suits small batches. Give one task exclusive access to each batch/rule instance. - Supply
it_hooks.new_idusing a reboot-safe sequence plus device-unique prefix or cryptographic randomness. IDs use at most 96 ASCII letters, digits, periods, hyphens or underscores. Use a durable sequence to avoid reuse after power loss. - Supply
it_hooks.storeto append a complete record to a flash journal (CRC plus commit marker) or deliver it to an acknowledged transport. Return success only after durable acceptance. The SDK clears its arena only on success. Retrying a sealed batch preserves byte-identical payload, trigger and ID. Retain the board's unresolved sealed arena until storage is available. An uncommitted RAM burst may be lost on power failure. - Convert driver measurements to named typed fields, then call
it_addwith event epoch milliseconds. Preserve monotonic timing separately in a value when absolute time is uncertain. Use numbers, booleans or printable ASCII strings; keys and stream names use the ID character set. Each sample accepts up to 32 fields and 4 KiB of encoded data. Large media belongs in the media API. - On
IT_FULLcommit the preceding burst withIT_SIZE, then retry that reading. A sample that cannot fit an empty buffer needs a larger buffer or a smaller schema. Callit_commitwithIT_TIMER,IT_CONTROL,IT_MANUALorIT_INCIDENTto flush on a scheduler deadline, an authenticated flush command, a manual request or a detected incident. A burst has at most 256 readings. - Feed linear acceleration (gravity removed, m/s²) and monotonic milliseconds to
it_detect_motion. A threshold crossing above the configured magnitude that clears the cooldown produces a local event; sustained high acceleration can retrigger after each cooldown. The board example records the motion and incident before sealing. Connect BLE, I²C, SPI, CAN, Modbus or a vendor SDK by mapping its readings toit_field. Seeexamples/rtos_adapter.cfor the compile-checked MCU-side adapter and board functions to implement.
it_field fix[] = {{"lat", IT_NUMBER, 28.61, NULL},
{"lon", IT_NUMBER, 77.21, NULL},
{"accuracyM", IT_NUMBER, 6, NULL}};
enum it_status status = it_add(&batch, "location", capture_unix_ms, fix, 3);
The POSIX host writes a private temporary file, syncs it, renames it and syncs its directory before releasing the RAM burst. A process-level filesystem lock makes file delivery single-writer. Up to 256 committed files, each at most 32 KiB, bound its spool. On restart, sync sends them in filename order. Successful delivery requires a 2xx receipt with the matching ID and sample count. A crash following server commit can replay a file; server-side idempotency prevents duplicate samples. Provision a supervisor or RTOS timer for jittered retries and heartbeat scheduling. The host example is a one-shot batch sender. Remote configuration polling, device authentication refresh, camera drivers, flash wear levelling and OTA require product-specific integration. The embedded adapter has been compile-tested; physical flash, radios, power-loss recovery and battery draw require target-board measurements.