Phase 2 of package refactor. Extracts trace parsing, ISO 15693 decoders, NDEF annotation, and ANSI formatting from core/hf_iso15.py into dedicated sniff/ modules: - sniff/trace.py — parse_tracelog (protocol-agnostic) - sniff/ndef.py — NDEF TLV/record decode - sniff/decode_iso15.py — 15693 command/response decoders - sniff/format.py — ANSI color formatting - sniff/session.py — SniffSession with iso15() method core/hf_iso15.py re-exports sniff symbols for backward compat. Also fixes NTAG 5 placement (iso15693, not iso14443a4) in design doc. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
"""Protocol-agnostic trace buffer parsing."""
|
|
import struct
|
|
|
|
# tracelog_hdr_t size: timestamp(4) + duration(2) + data_len_flags(2) = 8
|
|
TRACELOG_HDR_SIZE = 8
|
|
|
|
|
|
def parse_tracelog(raw: bytes) -> list[dict]:
|
|
"""Parse PM3 trace buffer into a list of trace entries.
|
|
|
|
Each entry: {timestamp, duration, is_response, data, parity}
|
|
"""
|
|
entries = []
|
|
offset = 0
|
|
while offset + TRACELOG_HDR_SIZE <= len(raw):
|
|
timestamp, duration, data_len_flags = struct.unpack_from("<IHH", raw, offset)
|
|
is_response = bool(data_len_flags & 0x8000)
|
|
data_len = data_len_flags & 0x7FFF
|
|
offset += TRACELOG_HDR_SIZE
|
|
|
|
if data_len == 0:
|
|
break # end of trace / sentinel
|
|
|
|
if offset + data_len > len(raw):
|
|
break
|
|
|
|
data = raw[offset:offset + data_len]
|
|
offset += data_len
|
|
|
|
parity_len = (data_len + 7) // 8 if data_len > 0 else 0
|
|
parity = raw[offset:offset + parity_len] if parity_len else b""
|
|
offset += parity_len
|
|
|
|
entries.append({
|
|
"timestamp": timestamp,
|
|
"duration": duration,
|
|
"is_response": is_response,
|
|
"data": data,
|
|
"parity": parity,
|
|
})
|
|
return entries
|