survive disconnect during BLE MTU lookup

This commit is contained in:
Jay
2026-08-18 14:26:11 -04:00
parent d86212be9d
commit 4bf00eb583
5 changed files with 35 additions and 3 deletions
+11 -1
View File
@@ -61,7 +61,17 @@ remains the nominal datasheet value. Mapped raw counts are stored directly, and
sensor-native counts are reconstructed losslessly from the documented mapping.
No software filtering or sensor fusion is performed yet.
The ESP32-C3 polls at exactly 100 Hz in a dedicated acquisition task, but each
The BLE reconnect fixture measured scheduling jitter without drift: among 2,575
contiguous sample intervals, 1,293 differed from exactly 10 ms; absolute timing
deviation had a 4 us median, 160 us p95, 170 us p99, and 780 us maximum, while
cumulative error was only 152 us over 25.75 seconds. Bluetooth tasks can preempt
the polling task, but every record carries its actual acquisition timestamp.
Future fusion, integration, and filtering must derive each `dt` from those
timestamps rather than assume a uniform 10 ms interval. Sensor DRDY/FIFO
acquisition remains the later refinement for reducing the jitter itself.
The ESP32-C3 schedules nominal 100 Hz polling in a dedicated acquisition task,
but each
sensor has an independent internal
sample clock. The status registers are read immediately before each XYZ read so a
consumer can distinguish a fresh sample from a repeated poll and identify gyro
+3 -1
View File
@@ -100,7 +100,9 @@ cumulative uint32 counters:
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.
counters remain zero. The rejected-ACK total can also include a harmless valid
duplicate that arrives after its frame has already completed, so a nonzero value
does not by itself prove corruption or a hostile receiver.
## Buffering
+10 -1
View File
@@ -50,10 +50,19 @@ therefore compare the sequence and raw bytes with their last persisted frame,
avoid writing a duplicate, and ACK the replay again. The reference
`tools/capture_ble.py` implements this ordering.
The rejected-ACK counter is diagnostic, not a pure corruption count. A valid
duplicate ACK can arrive after the output task has already completed that frame
and begun the next one; firmware then rejects and counts the now-stale write.
BLE notification success only means the fragment entered the stack. The `ACK1`
write is the end-to-end boundary. It deliberately confirms application
persistence rather than radio or ATT delivery alone.
Version 1 is an unauthenticated, single-connection prototype service. It does
not yet provide pairing, authorization, or confidentiality against a nearby
peer; those are separate from the loss/replay guarantees above.
peer; those are separate from the loss/replay guarantees above. A nearby peer
can also deny availability by subscribing and never acknowledging: firmware
correctly retains and replays the owned frame, but the RAM queue eventually
fills while the legitimate receiver remains excluded. Pairing and connection
authorization are required before treating this as a hostile-environment
logger.
+6
View File
@@ -340,6 +340,12 @@ static trikke_transport_status_t ble_poll_once(void *context)
portEXIT_CRITICAL(&ble->lock);
const uint16_t mtu = ble_att_mtu(connection_handle);
if (mtu == 0) {
// The connection can disappear after the locked state snapshot above.
// The GAP callback advances the delivery epoch; retain ownership and
// let a later poll restart the frame after resubscription.
return TRIKKE_TRANSPORT_PENDING;
}
if (mtu <= 3 + TRIKKE_BLE_FRAGMENT_HEADER_SIZE) {
return TRIKKE_TRANSPORT_FATAL;
}
+5
View File
@@ -63,6 +63,11 @@ removed before production firmware was built and flashed.
final status records one disconnect and one deliberate frame replay, with
zero notification failures or invalid ACKs. It validates that the 10.24-second
queue covered the measured resubscription interval without permanent loss.
Of its 2,575 contiguous sample intervals, 1,293 differ from exactly 10 ms.
Absolute deviation has a 4 us median, 160 us p95, 170 us p99, and 780 us
maximum; cumulative error is 152 us over 25.75 seconds. This records bounded
BLE scheduling jitter without rate drift and requires timestamp-derived `dt`
in future fusion work.
`tests/test_trikke_protocol.py` verifies the hashes, parses the captures in
fragmented chunks, and asserts these signatures so the hardware evidence remains