feat: add large BW→S3 write frame checksum validation in s3_parser

This commit is contained in:
serversdwn
2026-03-13 17:53:11 -04:00
parent 45f4fb5a68
commit 58a35a3afd
2 changed files with 73 additions and 6 deletions

View File

@@ -109,6 +109,28 @@ def _try_validate_sum8(body: bytes) -> Optional[Tuple[bytes, bytes, str]]:
return None
def _try_validate_sum8_large(body: bytes) -> Optional[Tuple[bytes, bytes, str]]:
"""
Large BW->S3 write frame checksum (SUBs 68, 69, 71, 82, 1A with data).
Formula: (sum(b for b in payload[2:-1] if b != 0x10) + 0x10) & 0xFF
- Starts from byte [2], skipping CMD (0x10) and DLE (0x10) at [0][1]
- Skips all 0x10 bytes in the covered range
- Adds 0x10 as a constant offset
- body[-1] is the checksum byte
Confirmed across 20 frames from two independent captures (2026-03-12).
"""
if len(body) < 3:
return None
payload = body[:-1]
chk = body[-1]
calc = (sum(b for b in payload[2:] if b != 0x10) + 0x10) & 0xFF
if calc == chk:
return payload, bytes([chk]), "SUM8_LARGE"
return None
def _try_validate_crc16(body: bytes) -> Optional[Tuple[bytes, bytes, str]]:
"""
body = payload + crc16(2 bytes)
@@ -137,11 +159,16 @@ def validate_bw_body_auto(body: bytes) -> Optional[Tuple[bytes, bytes, str]]:
Try to interpret the tail of body as a checksum in several ways.
Return (payload, checksum_bytes, checksum_type) if any match; else None.
"""
# Prefer SUM8 first (it fits small frames and is cheap)
# Prefer plain SUM8 first (small frames: POLL, read commands)
hit = _try_validate_sum8(body)
if hit:
return hit
# Large BW->S3 write frames (SUBs 68, 69, 71, 82, 1A with data)
hit = _try_validate_sum8_large(body)
if hit:
return hit
# Then CRC16 variants
hit = _try_validate_crc16(body)
if hit: