fix: add new helper (_recv_5a_batch()) that helps with assembling chunks over TCP
This commit is contained in:
@@ -685,64 +685,34 @@ def write_blastware_file(
|
||||
body_frames = a5_frames
|
||||
term_frame = None
|
||||
|
||||
# ── Identify first metadata frame and skip "extra chunks" ───────────────
|
||||
# When extra_chunks_after_metadata=1 in read_bulk_waveform_stream(), the
|
||||
# frame list is: [probe, data..., metadata, extra_chunk, terminator].
|
||||
# The extra_chunk is downloaded to prime the TCP terminator response — its
|
||||
# ADC data is NOT part of the Blastware file body. Skip it.
|
||||
#
|
||||
# Rule: any frame at index strictly between first_metadata_fi and last_fi
|
||||
# (the final frame) is an extra chunk and must be excluded.
|
||||
#
|
||||
# If no metadata frame exists (e.g. full_waveform download), first_metadata_fi
|
||||
# is None and no frames are skipped — all frames contribute normally.
|
||||
first_metadata_fi: Optional[int] = None
|
||||
for _fi_scan, _frame_scan in enumerate(body_frames):
|
||||
if _fi_scan > 0 and any(m in bytes(_frame_scan.data) for m in _METADATA_FRAME_MARKERS):
|
||||
first_metadata_fi = _fi_scan
|
||||
break
|
||||
last_fi = len(body_frames) - 1
|
||||
|
||||
log.warning(
|
||||
"write_blastware_file: %d body_frames first_metadata_fi=%s last_fi=%d",
|
||||
"write_blastware_file: %d body_frames term_idx=%s",
|
||||
len(body_frames),
|
||||
str(first_metadata_fi) if first_metadata_fi is not None else "None",
|
||||
last_fi,
|
||||
str(term_idx) if term_idx is not None else "None",
|
||||
)
|
||||
|
||||
all_bytes = bytearray()
|
||||
|
||||
for fi, frame in enumerate(body_frames):
|
||||
# Skip "extra chunk" frames: frames after the first metadata frame but
|
||||
# before the last frame (terminator). These prime the TCP terminator but
|
||||
# their ADC data must NOT appear in the Blastware file body.
|
||||
if (first_metadata_fi is not None
|
||||
and fi > first_metadata_fi
|
||||
and fi < last_fi):
|
||||
log.warning(
|
||||
"write_blastware_file: fi=%d SKIP (extra chunk after metadata fi=%d last_fi=%d)",
|
||||
fi, first_metadata_fi, last_fi,
|
||||
)
|
||||
continue
|
||||
|
||||
# All body frames contribute to the waveform body — no frames are skipped.
|
||||
#
|
||||
# Over TCP via cellular modem, _recv_5a_batch() correctly collects all
|
||||
# A5 frames per chunk request (the device's ~1100-byte RS-232 response
|
||||
# is forwarded as ~2 TCP segments of ~550 bytes each, each parsed as a
|
||||
# separate S3 frame). ALL of these frames contain ADC body data and
|
||||
# must be included in the file — confirmed from 4-27-26 TCP capture
|
||||
# analysis: contributions from all 14 frames → 6821 bytes → file 6864 bytes.
|
||||
#
|
||||
# Skip amounts (offsets into frame.data):
|
||||
# fi=0 (probe): probe_skip — skips the type_tag header + STRT record
|
||||
# fi=1: 13 — 7-byte frame.data prefix + 6 inner header bytes
|
||||
# fi>=2: 12 — 7-byte frame.data prefix + 5 inner header bytes
|
||||
if fi == 0:
|
||||
# Probe frame: always process regardless of classification.
|
||||
# It holds the STRT record; probe_skip positions us past it.
|
||||
skip = probe_skip
|
||||
elif fi == 1:
|
||||
skip = 13
|
||||
else:
|
||||
# ALL subsequent frames are included unconditionally — no filtering on
|
||||
# frame type. In the A5 stream, frame 0 is always the probe response;
|
||||
# frames 1+ are always data (waveform chunks, compliance config, or
|
||||
# compliance continuation). Classification is for logging only.
|
||||
#
|
||||
# DO NOT gate on classify_frame() here:
|
||||
# - "probe_or_strt" at fi>0 is always a false positive — ADC binary
|
||||
# data can coincidentally contain b"STRT\xff\xfe" (confirmed from
|
||||
# live capture: frames 1 and 5 matched on event key=01110000).
|
||||
# - "metadata" frames must be included (compliance config body).
|
||||
# - The compliance block spans 2 frames; skipping either produces a
|
||||
# truncated file that Blastware rejects.
|
||||
skip = 13 if fi == 1 else 12
|
||||
skip = 12
|
||||
|
||||
contribution = _frame_body_bytes(frame, skip)
|
||||
log.warning("write_blastware_file: fi=%d skip=%d raw_data=%d contribution=%d",
|
||||
|
||||
Reference in New Issue
Block a user