Skip to content

fix(vehicle): reset stale BLE reassembly frames#58

Merged
Bre77 merged 2 commits into
mainfrom
fm/tfa-ble-buffer-reset-hardening
Jul 10, 2026
Merged

fix(vehicle): reset stale BLE reassembly frames#58
Bre77 merged 2 commits into
mainfrom
fm/tfa-ble-buffer-reset-hardening

Conversation

@Bre77

@Bre77 Bre77 commented Jul 10, 2026

Copy link
Copy Markdown
Member

Intent

Add a time-based reset to ReassemblingBuffer (BLE reassembly), matching Tesla's official Go SDK. The Go SDK (teslamotors/vehicle-command, pkg/connector/ble/ble.go) resets its input buffer when more than rxTimeout (1s) passes since the last received chunk; our ReassemblingBuffer previously only resynchronized on a protobuf decode failure, so a chunk dropped mid-message could leave a stale partial frame in the buffer that gets prepended to the next message, corrupting it until a lucky decode error resynced. Fix: track last-chunk receive time via time.monotonic() in ReassemblingBuffer, added a module constant STALE_CHUNK_TIMEOUT = 1.0 matching the Go SDK's 1s value (no new config knob, per repo style), and discard the in-progress partial buffer if the next chunk arrives more than that long after the previous one, before appending the new data. Deliberately out of scope: exception wrapping, timeout/retry logic, and any change to the separate ack-loss/stalled-link behavior documented elsewhere in AGENTS.md (this is a frame-integrity hardening only, not a fix for that). Added two new mocked-clock tests to tests/test_ble_reassembling_buffer.py: one verifying a stale partial (>1s gap) is discarded so the following message decodes cleanly (confirmed this fails without the fix - the stale partial poisons the next message and it never decodes), and one verifying fast multi-chunk messages arriving under 1s apart still reassemble correctly as before. All existing tests, ruff, and pyright pass. Also added a short entry to AGENTS.md documenting the new reset semantics and Go SDK parity motivation, since it's durable project knowledge for future BLE work.

What Changed

  • Hardened BLE ReassemblingBuffer handling by tracking the last received chunk time and discarding stale partial frames after the 1-second inter-chunk timeout.
  • Added mocked-clock coverage for both stale partial-frame discard behavior and normal fast multi-chunk reassembly.
  • Documented the BLE stale-frame reset behavior in the Bluetooth vehicle docs and project agent notes.

Risk Assessment

✅ Low: The change is tightly scoped to BLE frame reassembly, preserves existing complete-message behavior, and adds focused regression coverage for the new stale-partial reset path.

Testing

Inspected the scoped BLE buffer diff, ran the targeted reassembly tests, captured a direct ReassemblingBuffer transcript proving stale partial discard and under-timeout reassembly behavior, then ran the full tests suite; all checks passed and transient worktree test artifacts were removed.

Evidence: BLE reassembly behavior transcript
STALE_CHUNK_TIMEOUT=1.0s
after partial VCSEC chunk at t=0.0s: decoded=0 buffer_bytes=12
after fresh INFO chunk at t=1.25s: decoded=['DOMAIN_INFOTAINMENT'] buffer_bytes=0
fast chunk offset=00 t=0.0s: decoded=0 buffer_bytes=5
fast chunk offset=05 t=0.1s: decoded=0 buffer_bytes=10
fast chunk offset=10 t=0.2s: decoded=0 buffer_bytes=15
fast chunk offset=15 t=0.3s: decoded=0 buffer_bytes=20
fast chunk offset=20 t=0.4s: decoded=1 buffer_bytes=0
fast reassembly result: decoded=['DOMAIN_VEHICLE_SECURITY'] request_uuid=0123456789abcdef

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • git diff --stat 759d6fa34108597ef09095771480318a39ac5b5a..113735ae3587357c45bc50b6dfe84aa58aefcbfd
  • git diff 759d6fa34108597ef09095771480318a39ac5b5a..113735ae3587357c45bc50b6dfe84aa58aefcbfd -- tesla_fleet_api/tesla/vehicle/bluetooth.py tests/test_ble_reassembling_buffer.py
  • uv run pytest tests/test_ble_reassembling_buffer.py
  • uv run python - <<'PY' | tee /tmp/no-mistakes-evidence/01KX4R7G5PPC2SG75829WYGSSB/ble-reassembling-buffer-transcript.txt
  • uv run pytest tests
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

firstmate crewmate added 2 commits July 10, 2026 10:53
ReassemblingBuffer only resynchronized on a protobuf decode failure, so a
chunk dropped mid-message left a stale partial frame that got prepended to
the next message, corrupting it until a lucky decode error resynced.
Discard the partial when a chunk arrives more than 1s after the previous
one, matching the reset semantics in Tesla's official Go SDK.
@Bre77 Bre77 merged commit 0800251 into main Jul 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant