fix(pm3py): disable CRC for USB (matching C client), fix CRC byte order for FPC UART

This commit is contained in:
michael
2026-03-16 00:03:23 -07:00
parent d9ec661d06
commit c015082b41
576 changed files with 201565 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
import struct
from pm3py.transport import encode_ng_frame, decode_response_frame, encode_mix_frame
from pm3py.protocol import Cmd, CMD_PREAMBLE_MAGIC, RESP_PREAMBLE_MAGIC, crc16_a
from pm3py.transport import encode_ng_frame, decode_response_frame, encode_mix_frame, _crc_to_wire
from pm3py.protocol import Cmd, CMD_PREAMBLE_MAGIC, CMD_POSTAMBLE_NOCRC, RESP_PREAMBLE_MAGIC, RESP_POSTAMBLE_NOCRC, crc16_a
def test_encode_ng_frame_ping_no_payload():
frame = encode_ng_frame(Cmd.PING, b"")
@@ -11,17 +11,26 @@ def test_encode_ng_frame_ping_no_payload():
assert length_ng & 0x8000 # ng bit set
assert (length_ng & 0x7FFF) == 0
assert cmd == Cmd.PING
# Default: no CRC (USB mode)
crc_actual = struct.unpack_from("<H", frame, 8)[0]
assert crc_actual == CMD_POSTAMBLE_NOCRC
def test_encode_ng_frame_with_payload():
def test_encode_ng_frame_with_payload_no_crc():
"""Default USB mode: no CRC, uses magic postamble."""
payload = bytes(range(32))
frame = encode_ng_frame(Cmd.PING, payload)
assert len(frame) == 10 + 32
_, length_ng, _ = struct.unpack_from("<IHH", frame, 0)
assert (length_ng & 0x7FFF) == 32
# verify payload in frame
assert frame[8:40] == payload
# verify CRC
crc_expected = crc16_a(frame[:40])
crc_actual = struct.unpack_from("<H", frame, 40)[0]
assert crc_actual == CMD_POSTAMBLE_NOCRC
def test_encode_ng_frame_with_crc():
"""FPC UART mode: real CRC, byte-swapped."""
payload = bytes(range(32))
frame = encode_ng_frame(Cmd.PING, payload, use_crc=True)
crc_expected = _crc_to_wire(crc16_a(frame[:40]))
crc_actual = struct.unpack_from("<H", frame, 40)[0]
assert crc_actual == crc_expected
@@ -31,14 +40,13 @@ def test_encode_mix_frame():
assert not (length_ng & 0x8000) # ng bit NOT set for MIX
assert (length_ng & 0x7FFF) == 24 # 3x uint64 = 24 bytes
def test_decode_response_frame_success():
# Build a fake response frame
def test_decode_response_frame_no_crc():
"""USB mode: response uses no-CRC magic."""
payload = b"\x01\x02\x03\x04"
length_ng = len(payload) | 0x8000
preamble = struct.pack("<IHbbH", RESP_PREAMBLE_MAGIC, length_ng, 0, 0, Cmd.PING)
body = preamble + payload
crc = crc16_a(body)
postamble = struct.pack("<H", crc)
postamble = struct.pack("<H", RESP_POSTAMBLE_NOCRC)
frame = body + postamble
resp = decode_response_frame(frame)
@@ -47,11 +55,25 @@ def test_decode_response_frame_success():
assert resp["data"] == payload
assert resp["ng"] is True
def test_decode_response_frame_with_crc():
"""FPC UART mode: response has real CRC, byte-swapped."""
payload = b"\x01\x02\x03\x04"
length_ng = len(payload) | 0x8000
preamble = struct.pack("<IHbbH", RESP_PREAMBLE_MAGIC, length_ng, 0, 0, Cmd.PING)
body = preamble + payload
crc = _crc_to_wire(crc16_a(body))
postamble = struct.pack("<H", crc)
frame = body + postamble
resp = decode_response_frame(frame)
assert resp["cmd"] == Cmd.PING
assert resp["status"] == 0
assert resp["data"] == payload
def test_decode_response_frame_error_status():
length_ng = 0 | 0x8000
preamble = struct.pack("<IHbbH", RESP_PREAMBLE_MAGIC, length_ng, -4, -1, Cmd.STATUS)
crc = crc16_a(preamble)
postamble = struct.pack("<H", crc)
postamble = struct.pack("<H", RESP_POSTAMBLE_NOCRC)
frame = preamble + postamble
resp = decode_response_frame(frame)