fix: Align CRC-16 calculation with ETSI EN 300 706 and improve retrieval
This commit is contained in:
@@ -77,18 +77,20 @@ class Page:
|
|||||||
|
|
||||||
def calculate_crc(self) -> int:
|
def calculate_crc(self) -> int:
|
||||||
"""
|
"""
|
||||||
Calculates the CRC-16 (CCITT) checksum for the page.
|
Calculates the CRC-16 checksum for the page.
|
||||||
According to ETSI EN 300 706 (Section 9.4.1.2 & Figure 13):
|
According to ETSI EN 300 706 (Section 9.6.1 & Figure 13):
|
||||||
- Covers Row 0 columns 8-31 (Bytes 14-37 in packet, excluding header and clock).
|
- G(x) = x^16 + x^12 + x^9 + x^7 + 1 (Poly 0x1281)
|
||||||
- Covers Rows 1-25 columns 0-39 (Bytes 6-45 in packet).
|
|
||||||
- Total 1024 bytes (8192 bits).
|
|
||||||
- Data is 7-bit (stripped parity).
|
|
||||||
- Initial value: 0.
|
- Initial value: 0.
|
||||||
|
- Processed bits b8 to b1 (MSB first for stored bytes).
|
||||||
|
- Total 1024 bytes (32 packets * 32 bytes).
|
||||||
|
- Packet X/0: Bytes 14 to 37 (24 bytes) + 8 spaces.
|
||||||
|
- Packets X/1 to X/25: Bytes 14 to 45 (32 bytes).
|
||||||
|
- Packets X/26 to X/31: 32 spaces each.
|
||||||
"""
|
"""
|
||||||
crc = 0
|
crc = 0
|
||||||
poly = 0x1021
|
poly = 0x1281
|
||||||
|
|
||||||
# Helper to update CRC with a byte
|
# Helper to update CRC with a byte (MSB first)
|
||||||
def update_crc(c, val):
|
def update_crc(c, val):
|
||||||
v = (val << 8) & 0xFFFF
|
v = (val << 8) & 0xFFFF
|
||||||
for _ in range(8):
|
for _ in range(8):
|
||||||
@@ -101,32 +103,38 @@ class Page:
|
|||||||
return c
|
return c
|
||||||
|
|
||||||
# Organize packets by row
|
# Organize packets by row
|
||||||
rows = {}
|
rows = {p.row: p for p in self.packets}
|
||||||
for p in self.packets:
|
|
||||||
rows[p.row] = p
|
for r in range(32): # Process 32 slots (0-31)
|
||||||
|
start, end = 0, 0
|
||||||
|
padding = 0
|
||||||
|
|
||||||
for r in range(26): # 0 to 25
|
|
||||||
# Determine column range
|
|
||||||
if r == 0:
|
if r == 0:
|
||||||
start_col, end_col = 8, 32 # Cols 8-31 (24 bytes)
|
# Row 0: Bytes 14-37 (24 bytes)
|
||||||
|
start, end = 8, 32 # data[8..31]
|
||||||
|
padding = 8
|
||||||
|
elif 1 <= r <= 25:
|
||||||
|
# Rows 1-25: Bytes 14-45 (32 bytes)
|
||||||
|
start, end = 8, 40 # data[8..39]
|
||||||
|
padding = 0
|
||||||
else:
|
else:
|
||||||
start_col, end_col = 0, 40 # Cols 0-39 (40 bytes)
|
# Rows 26-31: 32 spaces each
|
||||||
|
padding = 32
|
||||||
|
|
||||||
if r in rows:
|
# Process packet data if available
|
||||||
data = rows[r].data
|
if r in rows and start < end:
|
||||||
# Ensure data is long enough (should be 40)
|
p_data = rows[r].data
|
||||||
d_len = len(data)
|
for i in range(start, end):
|
||||||
|
byte_val = (p_data[i] & 0x7F) if i < len(p_data) else 0x20
|
||||||
for i in range(start_col, end_col):
|
|
||||||
if i < d_len:
|
|
||||||
byte_val = data[i] & 0x7F # Strip parity
|
|
||||||
else:
|
|
||||||
byte_val = 0x20 # Pad with space if short
|
|
||||||
crc = update_crc(crc, byte_val)
|
crc = update_crc(crc, byte_val)
|
||||||
else:
|
elif start < end:
|
||||||
# Missing row treated as spaces
|
# Missing packet but slot exists
|
||||||
for i in range(start_col, end_col):
|
for _ in range(start, end):
|
||||||
crc = update_crc(crc, 0x20)
|
crc = update_crc(crc, 0x20)
|
||||||
|
|
||||||
|
# Add padding for this slot
|
||||||
|
for _ in range(padding):
|
||||||
|
crc = update_crc(crc, 0x20)
|
||||||
|
|
||||||
return crc
|
return crc
|
||||||
|
|
||||||
@@ -140,15 +148,16 @@ class Page:
|
|||||||
if p.row == 27:
|
if p.row == 27:
|
||||||
# Check Designation Code (Byte 0)
|
# Check Designation Code (Byte 0)
|
||||||
try:
|
try:
|
||||||
b0 = p.data[0]
|
if len(p.data) >= 40:
|
||||||
# Decode Hamming 8/4
|
b0 = p.data[0]
|
||||||
designation = decode_hamming_8_4(b0)
|
# Decode Hamming 8/4
|
||||||
|
designation = decode_hamming_8_4(b0)
|
||||||
if designation == 0:
|
|
||||||
# Packet 27/0
|
# Packets X/27/0 to X/27/3 exist, but only X/27/0 has the CRC.
|
||||||
# Checksum is in bytes 38 and 39.
|
# We also check if b0 is raw 0 as a fallback for some captures.
|
||||||
# ETSI EN 300 706: 8 bits of each byte are used.
|
if designation == 0 or b0 == 0:
|
||||||
if len(p.data) >= 40:
|
# Packet 27/0
|
||||||
|
# Checksum is in bytes 38 and 39 (TBytes 44 and 45).
|
||||||
hi = p.data[38]
|
hi = p.data[38]
|
||||||
lo = p.data[39]
|
lo = p.data[39]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user