fix(protocol): enhance extra chunk fetching logic to ensure footer detection

This commit is contained in:
2026-04-23 18:22:27 -04:00
parent bc9f16e503
commit ecd980d345
2 changed files with 23 additions and 10 deletions
+17 -4
View File
@@ -652,8 +652,14 @@ class MiniMateProtocol:
# and primes the device to return a valid footer in the termination # and primes the device to return a valid footer in the termination
# response. Without it, termination returns an empty ack with no # response. Without it, termination returns an empty ack with no
# footer bytes (confirmed 2026-04-23 from HxD comparison). # footer bytes (confirmed 2026-04-23 from HxD comparison).
log.debug("5A A5[%d] metadata found — fetching %d more chunk(s) then stopping", # Download extra chunks until we find the footer chunk (contains
chunk_num, extra_chunks_after_metadata) # 0x0e 0x08 near its end) or hit the extra_chunks_after_metadata
# cap. The footer bytes are embedded in the last meaningful data
# chunk, NOT in the termination response. For short events (1-sec)
# the footer is in extra chunk 1. For longer events it is in a
# later chunk. Confirmed 2026-04-23 from BW file comparison.
log.debug("5A A5[%d] metadata found — fetching extra chunks until footer found",
chunk_num)
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 = chunk_num * _BULK_COUNTER_STEP
@@ -661,13 +667,20 @@ class MiniMateProtocol:
self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params)) self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params))
try: try:
extra = self._recv_one(expected_sub=rsp_sub, timeout=10.0) extra = self._recv_one(expected_sub=rsp_sub, timeout=10.0)
log.debug("5A A5[%d] extra chunk page_key=0x%04X data_len=%d", log.debug("5A A5[%d] extra chunk page_key=0x%04X data_len=%d has_footer=%s",
chunk_num, extra.page_key, len(extra.data)) chunk_num, extra.page_key, len(extra.data),
b'\x0e\x08' in extra.data[-50:])
if extra.page_key == 0x0000: if extra.page_key == 0x0000:
if include_terminator: if include_terminator:
frames_data.append(extra) frames_data.append(extra)
return frames_data return frames_data
frames_data.append(extra) frames_data.append(extra)
# Stop as soon as we find the footer marker in the tail
# of this chunk — the body is complete.
if b'\x0e\x08' in extra.data[-50:]:
log.debug("5A A5[%d] footer marker found — stopping extra chunks",
chunk_num)
break
except TimeoutError: except TimeoutError:
log.debug("5A extra chunk %d timed out — end of stream", _extra_n + 1) log.debug("5A extra chunk %d timed out — end of stream", _extra_n + 1)
break break
+6 -6
View File
@@ -885,17 +885,17 @@ def device_event_blastware_file(
def _do(): def _do():
with _build_client(port, baud, host, tcp_port, timeout=120.0) as client: with _build_client(port, baud, host, tcp_port, timeout=120.0) as client:
info = client.connect() info = client.connect()
# Calculate extra ADC chunks to download after finding "Project:". # Download extra chunks after "Project:" until the footer marker
# BW downloads ~2 extra chunks per second of record time. # 0x0e 0x08 is detected in a chunk tail. The cap prevents
# Without enough extra chunks the termination response contains no # accidentally downloading into post-event silence.
# footer bytes and Blastware rejects the file. # Cap = rectime * 4 + 4 covers up to ~10 sec events safely.
rectime = 1.0 rectime = 1.0
try: try:
rectime = float(info.compliance_config.record_time or 1.0) rectime = float(info.compliance_config.record_time or 1.0)
except (AttributeError, TypeError, ValueError): except (AttributeError, TypeError, ValueError):
pass pass
extra_chunks = max(1, int(rectime)) extra_chunks = max(4, int(rectime * 4) + 4)
log.info("blastware_file: rectime=%.1fs → extra_chunks=%d", rectime, extra_chunks) log.info("blastware_file: rectime=%.1fs → extra_chunks_cap=%d", rectime, extra_chunks)
events = client.get_events( events = client.get_events(
full_waveform=False, full_waveform=False,
stop_after_index=index, stop_after_index=index,