fix(protocol): update chunk counter formula to use max(key4[2:4], 0x0400) for accurate data streaming

This commit is contained in:
2026-04-26 01:28:47 -04:00
parent 7976b544ed
commit 2f084ed105
3 changed files with 56 additions and 39 deletions
+17 -16
View File
@@ -118,28 +118,29 @@ S3→BW (response):
Both differences confirmed by reproducing Blastware's exact wire bytes from the 1-2-26
BW TX capture. All 10 frames verified.
### SUB 5A — chunk counter formula (FINAL CORRECTION 2026-04-24)
### SUB 5A — chunk counter formula (FINAL CORRECTION 2026-04-26)
**Chunk counter = `key4[2:4] + (chunk_num - 1) * 0x0400` for ALL chunks.**
**Chunk counter = `max(key4[2:4], 0x0400) + (chunk_num - 1) * 0x0400` for ALL chunks.**
where `key4[2:4] = (key4[2] << 8) | key4[3]` is the event's circular-buffer base offset.
The 4-2-26 BW TX capture showed `counter=0x1004` for chunk 1 of event key `01110000`, which
led to `_CHUNK1_COUNTER = 0x1004` being hardcoded as a special case. This was a Blastware
artifact, not a protocol requirement. Empirical test 2026-04-06: with `counter=0x1004` for
chunk 1 the device times out (120 s); with `counter=0x0400` (= `1 * 0x0400`) it responds
immediately and streams all frames correctly.
The `max(..., 0x0400)` guard is critical for events at the start of the circular buffer
(key4[2:4] == 0x0000, e.g. key `01110000`). Without it, chunk 1 gets counter=0x0000, which
is the same address as the probe frame — the device re-returns the STRT record data instead
of waveform payload. With the guard, chunk 1 gets counter=0x0400, which is confirmed correct
from the empirical live-device test 2026-04-06 (`counter=0x0400 → responds immediately and
streams all frames correctly`).
The 4-3-26 capture confirms the pattern for a second event (key `0111245a`):
chunk 1 = `0x245A`, chunk 2 = `0x285A`, chunk 3 = `0x2C5A` (each +0x0400). Blastware's
true formula is `key4[2:4] + (chunk_num - 1) * 0x0400`.
The 4-3-26 capture confirms the pattern for a second event (key `0111245a`, key4[2:4]=0x245a):
chunk 1 = `0x245A`, chunk 2 = `0x285A`, chunk 3 = `0x2C5A` (each +0x0400).
`max(0x245a, 0x0400) = 0x245a` → formula works correctly for non-zero base offset too.
**2026-04-24 CORRECTION — `n * 0x0400` is WRONG for non-first events.** For event key
`01110000`, `key4[2:4] == 0x0000` so the old `chunk_num * 0x0400` formula was accidentally
correct. For keys with `key4[2:4] != 0` (e.g. key `01111884`, offset `0x1884`), the old
formula sends counters pointing into the wrong buffer region — the device returns data from
a completely different stored event and `b"Project:"` never appears in the stream.
Use `key4[2:4] + (chunk_num - 1) * 0x0400` exclusively.
**History:**
- Original: `_CHUNK1_COUNTER = 0x1004` hardcoded (Blastware capture artifact — WRONG).
- 2026-04-06: Corrected to `chunk_num * 0x0400` (worked for key 01110000 only).
- 2026-04-24: Corrected to `key4[2:4] + (chunk_num-1) * 0x0400` (fixed non-zero offsets,
but accidentally broke key 01110000 — counter=0x0000 sends probe address again).
- 2026-04-26: Final formula: `max(key4[2:4], 0x0400) + (chunk_num-1) * 0x0400`.
### SUB 5A — params are 11 bytes for chunk frames, 10 for termination