Skip to content

ZeroTrace AirLeak

RPC Reference

The BLE JSON-RPC methods the app uses to control the unit

AirLeak has no serial console and no CLI. The mobile app controls the unit entirely over a Bluetooth link using JSON-RPC 2.0 on the Nordic UART Service (NUS); the capture stream rides a separate dedicated BLE characteristic. You don't normally call these directly, the app's tabs do, but this is the surface they use (src/handlers/, src/transport/rpc_dispatch.cpp).

Authenticated

Most methods require the unit to be licensed (the dispatcher gates them at the Licensed auth level). An unlicensed unit accepts pairing and license activation so the app can bring it online.


Identity

identity.read

Returns the unit's identity: device name, firmware_type (airleak), firmware version, HWID, and the licensed flag. The app reads this on every connect to pick the right device UI and gate licensing.


License

HWID-bound license activation, identical to the other ZeroTrace firmware families.

MethodBehaviour
license.requestBegin activation for this HWID
license.setStore a license key (the app sends the scanned/typed key)
license.statusReport current license state

Capture stays held in setup until a valid key is stored.


Configuration

MethodBehaviour
config.getReturn the current settings document (/config.json on LittleFS) plus read-only fields (product name, firmware version, serial, storage)
config.setWrite one key; rejected if the key isn't a known setting

See the Settings Reference for every key and default.


Mode

MethodBehaviour
mode.readReturn the current mode
mode.setValidate, apply, and persist a mode

Accepted modes: setup, self_test, room_scan, monitor, recon, stalker_hunt, wardrive. The retired mdns_audit / travel values are rejected. See Capture Modes.


State

state.read

A live health snapshot for the app's status readouts:

FieldMeaning
uptime_msTime since boot
heap_freeFree internal heap (bytes)
modeCurrent mode
devices_activeDevices in the live aggregator
drop_countDelta-ring overflow count (deltas dropped under backpressure)
raw_drop_countRaw advertisements dropped before parsing
ev_per_secRolling 1 s ingest rate
lowest_heapLowest free heap seen
safe_mode / safe_mode_triggersSafe-mode state + trigger count
scan_duty_pctEstimated BLE scan duty cycle (window ÷ interval); an upper bound while a phone is connected

See Heartbeat / state fields for detail.


Capture stream

MethodBehaviour
capture.snapshotFull current device table + the current sequence number
capture.sinceDeltas since a sequence number, or a {reset, snapshot} if the ring wrapped
capture.subscribe / capture.unsubscribeStart / stop CBOR delta notifications on the capture characteristic

The stream is device-centric and coalesced, one logical row per MAC with deltas on meaningful change, not a raw per-advertisement firehose. See Throttle & emit policy.


LED

led.set

Preview an LED color. LED behaviour (startup color, brightness, mode/threat indication) is otherwise driven by config keys, see Settings.


Diagnostics

MethodBehaviour
diag.readRead the on-flash crash / heap / boot diagnostic log
diag.clearClear it

This persistent log is how post-mortem health (e.g. a heap-exhaustion freeze) is recovered after the fact, since the live capture stream is not buffered.


TraceNet (swarm)

MethodBehaviour
node.enable / list / approve / remove / commandManage ESP-NOW swarm nodes that feed advertisements to this hub

TraceNet is off by default (swarm_enabled config key). It's surfaced in the app's TraceNet tab and the Drive swarm panel.


Factory reset

Removing a license / wiping settings is handled through the app, not a device command. To clear all settings the app rewrites /config.json to defaults via config.set, and re-licensing is done over the BLE license methods above.