fix(analyzer): name A5/5A frames; revert S3 checksum validation
Add 0x5A (BULK_WAVEFORM_STREAM) and 0xA5 (BULK_WAVEFORM_RESPONSE) to SUB_TABLE so they display with real names instead of UNKNOWN_5A/A5. Revert S3 checksum validation to checksum_valid=None (the original intentional behavior). Large S3 frames (A5 bulk waveform, E5 compliance config) embed inner DLE+ETX sub-frame delimiters; the trailing 0x03 of the last inner delimiter can land where the parser expects the SUM8 checksum byte, causing false BAD CHK on every valid A5 frame. protocol.py _validate_frame documents and ignores exactly this issue. https://claude.ai/code/session_014NczSHUz9uTzCAf4cVASTJ
This commit is contained in:
@@ -53,7 +53,9 @@ SUB_TABLE: dict[int, tuple[str, str, str]] = {
|
|||||||
0x82: ("TRIGGER_CONFIG_WRITE", "BW→S3", "0x1C bytes; trigger config block; mirrors SUB 1C"),
|
0x82: ("TRIGGER_CONFIG_WRITE", "BW→S3", "0x1C bytes; trigger config block; mirrors SUB 1C"),
|
||||||
0x83: ("TRIGGER_WRITE_CONFIRM", "BW→S3", "Short frame; commit step after 0x82"),
|
0x83: ("TRIGGER_WRITE_CONFIRM", "BW→S3", "Short frame; commit step after 0x82"),
|
||||||
# S3→BW responses
|
# S3→BW responses
|
||||||
|
0x5A: ("BULK_WAVEFORM_STREAM", "BW→S3", "Bulk waveform chunk request; response is A5 stream"),
|
||||||
0xA4: ("POLL_RESPONSE", "S3→BW", "Response to SUB 5B poll"),
|
0xA4: ("POLL_RESPONSE", "S3→BW", "Response to SUB 5B poll"),
|
||||||
|
0xA5: ("BULK_WAVEFORM_RESPONSE", "S3→BW", "Response to SUB 5A; waveform chunks + metadata"),
|
||||||
0xFE: ("FULL_CONFIG_RESPONSE", "S3→BW", "Response to SUB 01"),
|
0xFE: ("FULL_CONFIG_RESPONSE", "S3→BW", "Response to SUB 01"),
|
||||||
0xF9: ("CHANNEL_CONFIG_RESPONSE", "S3→BW", "Response to SUB 06"),
|
0xF9: ("CHANNEL_CONFIG_RESPONSE", "S3→BW", "Response to SUB 06"),
|
||||||
0xF7: ("EVENT_INDEX_RESPONSE", "S3→BW", "Response to SUB 08; contains backlight/power-save"),
|
0xF7: ("EVENT_INDEX_RESPONSE", "S3→BW", "Response to SUB 08; contains backlight/power-save"),
|
||||||
|
|||||||
+11
-21
@@ -33,7 +33,7 @@ STX = 0x02
|
|||||||
ETX = 0x03
|
ETX = 0x03
|
||||||
ACK = 0x41
|
ACK = 0x41
|
||||||
|
|
||||||
__version__ = "0.2.4"
|
__version__ = "0.2.5"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -220,32 +220,22 @@ def parse_s3(blob: bytes, trailer_len: int) -> List[Frame]:
|
|||||||
trailer_end = trailer_start + trailer_len
|
trailer_end = trailer_start + trailer_len
|
||||||
trailer = blob[trailer_start:trailer_end]
|
trailer = blob[trailer_start:trailer_end]
|
||||||
|
|
||||||
chk_valid = None
|
# S3 checksums are deliberately not validated here.
|
||||||
chk_type = None
|
# Large S3 responses (A5 bulk waveform, E5 compliance) embed
|
||||||
chk_hex = None
|
# inner DLE+ETX sub-frame terminators whose trailing 0x03 byte
|
||||||
payload = bytes(body)
|
# lands where the parser would expect the SUM8 checksum, causing
|
||||||
|
# false failures. The live protocol (protocol.py _validate_frame)
|
||||||
if len(body) >= 1:
|
# also skips S3 checksum enforcement for the same reason.
|
||||||
received_chk = body[-1]
|
|
||||||
computed_chk = checksum8_sum(bytes(body[:-1]))
|
|
||||||
if computed_chk == received_chk:
|
|
||||||
chk_valid = True
|
|
||||||
chk_type = "SUM8"
|
|
||||||
chk_hex = f"{received_chk:02x}"
|
|
||||||
payload = bytes(body[:-1])
|
|
||||||
else:
|
|
||||||
chk_valid = False
|
|
||||||
|
|
||||||
frames.append(Frame(
|
frames.append(Frame(
|
||||||
index=idx,
|
index=idx,
|
||||||
start_offset=start_offset,
|
start_offset=start_offset,
|
||||||
end_offset=end_offset,
|
end_offset=end_offset,
|
||||||
payload_raw=bytes(body),
|
payload_raw=bytes(body),
|
||||||
payload=payload,
|
payload=bytes(body),
|
||||||
trailer=trailer,
|
trailer=trailer,
|
||||||
checksum_valid=chk_valid,
|
checksum_valid=None,
|
||||||
checksum_type=chk_type,
|
checksum_type=None,
|
||||||
checksum_hex=chk_hex
|
checksum_hex=None
|
||||||
))
|
))
|
||||||
|
|
||||||
idx += 1
|
idx += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user