fix(protocol): correct chunk counter formula for accurate data streaming

This commit is contained in:
2026-04-24 12:52:02 -04:00
parent 03540fdc00
commit 242666f358
+19 -8
View File
@@ -583,8 +583,17 @@ class MiniMateProtocol:
frames_data: list[S3Frame] = [] frames_data: list[S3Frame] = []
counter = 0 counter = 0
# BW counter formula (confirmed from 4-3-26 capture for key 0111245a):
# counter for chunk n = key4[2:4] + (n - 1) * 0x0400
# key4[2:4] is the event's circular-buffer base offset — without it, chunk
# requests address the wrong region of the device buffer and the device
# streams data from the wrong event (no "Project:" in any response).
# PREVIOUSLY WRONG NOTE: "device does not validate counter; chunk_num*0x0400
# is correct" — that was only true for key 01110000 where key4[2:4]==0x0000.
_key4_offset = (key4[2] << 8) | key4[3]
# ── Step 1: probe ──────────────────────────────────────────────────── # ── Step 1: probe ────────────────────────────────────────────────────
log.debug("5A probe key=%s", key4.hex()) log.debug("5A probe key=%s key4_offset=0x%04X", key4.hex(), _key4_offset)
params = bulk_waveform_params(key4, 0, is_probe=True) params = bulk_waveform_params(key4, 0, is_probe=True)
self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params)) self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params))
self._parser.reset() # reset bytes_fed counter before probe recv self._parser.reset() # reset bytes_fed counter before probe recv
@@ -601,13 +610,15 @@ class MiniMateProtocol:
log.debug("5A A5[0] page_key=0x%04X %d bytes", rsp.page_key, len(rsp.data)) log.debug("5A A5[0] page_key=0x%04X %d bytes", rsp.page_key, len(rsp.data))
# ── Step 2: chunk loop ─────────────────────────────────────────────── # ── Step 2: chunk loop ───────────────────────────────────────────────
# Chunk counters are monotonic: chunk_num * 0x0400 for all chunks. # Correct counter formula: key4[2:4] + (chunk_num - 1) * 0x0400
# The 4-2-26 BW TX capture showed 0x1004 for chunk 1, but this is a # This matches Blastware exactly (confirmed from 4-3-26 capture).
# Blastware artifact — the device accepts any counter value and streams # For events where key4[2:4]==0 (e.g. 01110000), this gives the same
# data regardless. Empirically confirmed 2026-04-06: 0x0400 for chunk 1 # result as the old chunk_num*0x0400 formula shifted by one step, which
# works; 0x1004 causes the device to ignore the frame (timeout). # the device also accepted — but for events with a non-zero base offset
# (e.g. key 01111884 with key4[2:4]=0x1884) the old formula sends
# completely wrong counters and the device streams the wrong buffer region.
for chunk_num in range(1, max_chunks + 1): for chunk_num in range(1, max_chunks + 1):
counter = chunk_num * _BULK_COUNTER_STEP counter = _key4_offset + (chunk_num - 1) * _BULK_COUNTER_STEP
params = bulk_waveform_params(key4, counter) params = bulk_waveform_params(key4, counter)
log.debug("5A chunk %d counter=0x%04X", chunk_num, counter) log.debug("5A chunk %d counter=0x%04X", chunk_num, counter)
self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params)) self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params))
@@ -662,7 +673,7 @@ class MiniMateProtocol:
chunk_num, extra_chunks_after_metadata) chunk_num, extra_chunks_after_metadata)
for _extra_n in range(extra_chunks_after_metadata): for _extra_n in range(extra_chunks_after_metadata):
chunk_num += 1 chunk_num += 1
counter = chunk_num * _BULK_COUNTER_STEP counter = _key4_offset + (chunk_num - 1) * _BULK_COUNTER_STEP
params = bulk_waveform_params(key4, counter) params = bulk_waveform_params(key4, counter)
self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params)) self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params))
try: try: