Big transponder support update
This commit is contained in:
115
tests/test_sim_st25dv.py
Normal file
115
tests/test_sim_st25dv.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""Tests for the ST25DV04K/16K/64K (ISO 15693 + I2C dynamic tag, RF side)."""
|
||||
import asyncio
|
||||
import struct
|
||||
import pytest
|
||||
|
||||
from pm3py.sim.frame import RFFrame
|
||||
from pm3py.transponders.hf.iso15693.st.st25dv import (
|
||||
ST25DV04K, ST25DV16K, ST25DV64K, REG_ENDA1, REG_RFA2SS, DYN_MB_CTRL,
|
||||
)
|
||||
|
||||
|
||||
def run(coro):
|
||||
return asyncio.new_event_loop().run_until_complete(coro)
|
||||
|
||||
|
||||
def cmd(tag, payload: bytes):
|
||||
return run(tag.handle_frame(RFFrame.from_bytes(payload)))
|
||||
|
||||
|
||||
class TestIdentity:
|
||||
@pytest.mark.parametrize("cls,prefix,blocks", [
|
||||
(ST25DV04K, b"\xE0\x02\x24", 128),
|
||||
(ST25DV16K, b"\xE0\x02\x26", 512),
|
||||
(ST25DV64K, b"\xE0\x02\x26", 2048),
|
||||
])
|
||||
def test_uid_and_blocks(self, cls, prefix, blocks):
|
||||
tag = cls()
|
||||
assert tag._uid[0:3] == prefix
|
||||
assert tag._num_blocks == blocks
|
||||
|
||||
def test_04k_sysinfo_has_memsize(self):
|
||||
tag = ST25DV04K()
|
||||
run(tag.power_on())
|
||||
r = cmd(tag, bytes([0x02, 0x2B]))
|
||||
assert r.data[1] == 0x0F
|
||||
assert r.data[-1] == 0x24 # IC ref
|
||||
assert r.data[-3] == 0x7F # 128 blocks - 1
|
||||
|
||||
def test_16k_sysinfo_omits_memsize(self):
|
||||
tag = ST25DV16K()
|
||||
run(tag.power_on())
|
||||
r = cmd(tag, bytes([0x02, 0x2B]))
|
||||
assert r.data[1] == 0x0B # DSFID+AFI+ICref, no memsize
|
||||
assert r.data[-1] == 0x26
|
||||
|
||||
def test_ext_sysinfo_gives_memsize(self):
|
||||
tag = ST25DV64K()
|
||||
run(tag.power_on())
|
||||
r = cmd(tag, bytes([0x02, 0x3B, 0x02, 0x0F]))
|
||||
assert struct.unpack_from("<H", r.data, 12)[0] == 2047
|
||||
|
||||
|
||||
class TestBlocks:
|
||||
def test_read_write(self):
|
||||
tag = ST25DV04K()
|
||||
run(tag.power_on())
|
||||
cmd(tag, bytes([0x02, 0x21, 0x08, 0xDE, 0xAD, 0xBE, 0xEF]))
|
||||
assert cmd(tag, bytes([0x02, 0x20, 0x08])).data[1:5] == b"\xDE\xAD\xBE\xEF"
|
||||
|
||||
def test_extended_read_write_high_block(self):
|
||||
tag = ST25DV16K()
|
||||
run(tag.power_on())
|
||||
cmd(tag, bytes([0x02, 0x31]) + struct.pack("<H", 300) + b"\x11\x22\x33\x44")
|
||||
r = cmd(tag, bytes([0x02, 0x30]) + struct.pack("<H", 300))
|
||||
assert r.data[1:5] == b"\x11\x22\x33\x44"
|
||||
|
||||
def test_fast_read_single(self):
|
||||
tag = ST25DV04K()
|
||||
run(tag.power_on())
|
||||
cmd(tag, bytes([0x02, 0x21, 0x08, 1, 2, 3, 4]))
|
||||
r = cmd(tag, bytes([0x02, 0xC0, 0x02, 0x08]))
|
||||
assert r.data[1:5] == b"\x01\x02\x03\x04"
|
||||
|
||||
|
||||
class TestPasswordConfig:
|
||||
def test_present_password_and_write_config(self):
|
||||
tag = ST25DV04K()
|
||||
run(tag.power_on())
|
||||
# write config denied without config session
|
||||
assert cmd(tag, bytes([0x02, 0xA1, 0x02, REG_ENDA1, 0x03])).data[0] == 0x01
|
||||
assert cmd(tag, bytes([0x02, 0xB3, 0x02, 0x00]) + bytes(8)).data[0] == 0x00
|
||||
assert cmd(tag, bytes([0x02, 0xA1, 0x02, REG_ENDA1, 0x03])).data[0] == 0x00
|
||||
assert cmd(tag, bytes([0x02, 0xA0, 0x02, REG_ENDA1])).data[1] == 0x03
|
||||
|
||||
def test_wrong_password(self):
|
||||
tag = ST25DV04K(passwords={0: b"\x01" * 8, 1: bytes(8), 2: bytes(8), 3: bytes(8)})
|
||||
run(tag.power_on())
|
||||
assert cmd(tag, bytes([0x02, 0xB3, 0x02, 0x00]) + bytes(8)).data[0] == 0x01
|
||||
|
||||
def test_area_read_protection(self):
|
||||
pw1 = b"\x01\x02\x03\x04\x05\x06\x07\x08"
|
||||
tag = ST25DV04K(passwords={0: bytes(8), 1: pw1, 2: bytes(8), 3: bytes(8)})
|
||||
run(tag.power_on())
|
||||
cmd(tag, bytes([0x02, 0xB3, 0x02, 0x00]) + bytes(8)) # config session
|
||||
cmd(tag, bytes([0x02, 0xA1, 0x02, REG_ENDA1, 0x00])) # Area1 = blocks 0-7
|
||||
cmd(tag, bytes([0x02, 0xA1, 0x02, REG_RFA2SS, 0x09])) # A2 rwprot=10, pwd_ctrl=1
|
||||
r = cmd(tag, bytes([0x02, 0x20, 20])) # block in Area2
|
||||
assert r.data[0] == 0x01 and r.data[1] == 0x15
|
||||
assert cmd(tag, bytes([0x02, 0xB3, 0x02, 0x01]) + pw1).data[0] == 0x00
|
||||
assert cmd(tag, bytes([0x02, 0x20, 20])).data[0] == 0x00
|
||||
|
||||
|
||||
class TestMailbox:
|
||||
def test_mailbox_round_trip(self):
|
||||
tag = ST25DV04K()
|
||||
run(tag.power_on())
|
||||
# mailbox disabled → error
|
||||
assert cmd(tag, bytes([0x02, 0xAB, 0x02])).data[0] == 0x01
|
||||
# enable via dynamic register MB_CTRL_Dyn b0
|
||||
cmd(tag, bytes([0x02, 0xAE, 0x02, DYN_MB_CTRL, 0x01]))
|
||||
msg = b"hello"
|
||||
cmd(tag, bytes([0x02, 0xAA, 0x02, len(msg) - 1]) + msg)
|
||||
assert cmd(tag, bytes([0x02, 0xAB, 0x02])).data[1] == len(msg) - 1
|
||||
r = cmd(tag, bytes([0x02, 0xAC, 0x02, 0x00, len(msg) - 1]))
|
||||
assert r.data[1:1 + len(msg)] == msg
|
||||
Reference in New Issue
Block a user