ZeroTrace AirLeak
State & Health Fields
Every field the unit reports through state.read
The app reads the unit's live health by calling the state.read RPC (see RPC Reference) over Bluetooth, on a short interval while connected. This page documents every field it returns (src/handlers/state_rpc.cpp).
There is no USB serial heartbeat in the shipping firmware. Health is a pull, the app calls state.read, not a push of HB: lines over a cable. Persistent post-mortem health lives in the on-flash diagnostic log (diag.read).
Field reference
| Field | Type | Meaning |
|---|---|---|
uptime_ms | integer | Time since last boot, in milliseconds |
heap_free | integer | Free internal heap, in bytes |
mode | string | Current capture mode |
devices_active | integer | Devices currently in the live aggregator |
drop_count | integer | Delta-ring overflow count, capture deltas dropped under backpressure |
raw_drop_count | integer | Raw advertisements dropped before parsing (radio queue overflow) |
ev_per_sec | float | Rolling ingest rate over the trailing ~1 s |
lowest_heap | integer | Lowest free heap seen since boot |
safe_mode | bool | True if the heap monitor is currently in safe mode |
safe_mode_triggers | integer | Number of times safe mode has armed since boot |
scan_duty_pct | integer | Estimated BLE scan duty cycle |
About scan_duty_pct
This is an estimate, not a measured on-air figure. It's derived purely from the configured scan window and interval:
duty ≈ round(100 × window / interval)
It reads 0 when the scanner isn't running. Crucially, while a phone is connected the radio time-slices between the connection and the scan, so the link steals air-time the scanner would otherwise use, in that case the reported value is an upper bound on the realized duty, not the actual figure. The app labels it accordingly.
About the drop counters
Two independent drop counters tell you where pressure is, if any:
raw_drop_countclimbs when advertisements arrive faster than the parser can drain the raw queue (very dense RF).drop_countclimbs when coalesced deltas can't be pushed because the BLE notify buffers are full; the device-delta ring absorbs the burst and, on overflow, drops the oldest and signals the app to re-snapshot.
Healthy operation keeps both flat. A single capture.dropped event prompts the app to re-fetch a full capture.snapshot, so a momentary drop self-heals rather than corrupting the live table.
Heap health
heap_free and lowest_heap are the numbers to watch. The heap monitor samples internal heap once per second and acts on these thresholds (see Safe Mode):
- below ~28 KB, soft warning
- below ~25 KB, safe mode arms (the aggregator stops admitting new devices)
- recovers at ~40 KB
Free heap. If it stays comfortably above the safe-mode threshold through a long capture, the unit is healthy. If lowest_heap is creeping toward 25 KB and safe_mode_triggers is climbing, the environment is dense enough to pressure the unit, see Safe Mode.