add reliable BLE telemetry transport

This commit is contained in:
Jay
2026-08-18 06:24:10 -04:00
parent 00f52ecf0f
commit 7617010d8e
26 changed files with 1499 additions and 47 deletions
+31 -5
View File
@@ -11,7 +11,7 @@ combined by an underlying byte transport.
| ---: | ---: | --- |
| 0 | 4 | ASCII magic `TRK1` |
| 4 | 1 | Wire version (`1`) |
| 5 | 1 | Packet type: metadata `1`, samples `2` |
| 5 | 1 | Packet type: metadata `1`, samples `2`, status `3` |
| 6 | 1 | Header size (`36`) |
| 7 | 1 | Record size (`0` or `20`) |
| 8 | 1 | Record count (`0` or 18) |
@@ -51,7 +51,11 @@ timestamp is reconstructed by cumulatively adding its delta. Firmware ends the
current packet before a delta exceeds the representable 655.35 ms range, making
the next sample the exact base timestamp of a new packet. As a defensive encoder
fallback, an unrepresentable delta is stored as `0xFFFF` and sets packet flag bit
0. Sample sequence gaps remain detectable independently.
0. Because intra-packet deltas are rounded to 10 us while each packet base keeps
the exact ESP timer value, an integrity check for an exact 10,000 us interval can
report up to +/-5 us at packet boundaries; changing the transport's packet size
changes how often that harmless quantization boundary appears. Sample sequence
gaps remain detectable independently.
Mapped raw counts are authoritative. The original sensor-native axes can be
reconstructed because the mappings are lossless:
@@ -76,6 +80,28 @@ A byte-stream receiver may begin inside an incomplete frame. It discards bytes
until a magic/header/CRC combination validates. Host tools report any rejection
before that first valid frame separately from CRC failures after synchronization.
## Status payload (32 bytes)
Status frames use packet type `3`, record size/count zero, and payload version
`1`. They are emitted at startup and approximately every five seconds. Offsets
0 and 2 are uint16 payload version and payload size; the remaining fields are
cumulative uint32 counters:
| Offset | Field |
| ---: | --- |
| 4 | Sensor read failures |
| 8 | Sample-queue overflows |
| 12 | Initial transport submissions that accepted zero bytes |
| 16 | BLE disconnects after a connection was established |
| 20 | BLE notification enqueue/send failures |
| 24 | BLE frame replays after disconnect, subscription change, or ACK timeout |
| 28 | Malformed, stale, premature, or wrong-connection ACK writes |
The header's cumulative dropped-sample count remains the sum of sensor read
failures and queue overflows, preserving version-1 receiver compatibility while
the status payload makes the causes independently observable. USB-specific BLE
counters remain zero.
## Buffering
Acquisition runs in a dedicated higher-priority task and writes complete samples
@@ -106,9 +132,9 @@ USB drain is not end-to-end application delivery confirmation. A host process
may attach after earlier frames have already left the endpoint, or fail after
the endpoint accepts them. CRC and sequence checks make resulting loss visible,
but an application acknowledgement and replay window are still required to
guarantee receipt. Accordingly, USB `COMPLETE` means endpoint drain, while the
planned reliable BLE backend will reserve `COMPLETE` for an application ACK of
the exact frame.
guarantee receipt. Accordingly, USB `COMPLETE` means endpoint drain, while
reliable BLE reserves `COMPLETE` for an application ACK of the exact frame. See
`ble-transport-v1.md` for fragmentation, replay, and UUIDs.
Receivers report bytes left in an incomplete trailing frame when capture ends.
Those bytes cannot pass CRC validation and are not silently admitted as samples.