feat(rawcli): NTAG 5 datasheet catalog (config + SRAM + pick-random-UID)
_NTAG5 = the SLIX2 command set minus STAY_QUIET_PERSISTENT (which NTAG5 rejects per the NTP5210/NTA5332 tables) plus the NTAG5-specific NXP customs: READ_CONFIG (0xC0), WRITE_CONFIG (0xC1, session registers 0xA0 STATUS_REG / 0xA1 CONFIG_REG), PICK_RANDOM_UID (0xC2), and READ_SRAM (0xD2) / WRITE_SRAM (0xD3) for the Link/Boost variants. Sourced from transponders/hf/iso15693/nxp/ntag5_*, routed by catalog_for, verified live. Not yet wired: auto-identify of NTAG5. NTAG5 and ICODE DNA share UID E0 04 01 18, so they can't be told apart by UID — routing needs a functional probe (READ_CONFIG of a session register), which needs a brief NTAG5 tap to nail without risking DNA misclassification. AES/ISO-29167-10 commands (0x35/0x39/0x3A) noted as a follow-up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@ from pm3py.cli.rawcli.trace_view import render_exchange
|
||||
from pm3py.cli.rawcli.parser import parse_token, parse_bytes, parse_line
|
||||
from pm3py.cli.rawcli.entry import type_digit, is_byte_line, reconcile_bases
|
||||
from pm3py.cli.rawcli.identify import identify, clear, name_14a, format_summary
|
||||
from pm3py.cli.rawcli.catalog import (TYPE2, ISO15, T5577, LF_READONLY, MFC, _SLIX, _SLIX2,
|
||||
from pm3py.cli.rawcli.catalog import (TYPE2, ISO15, T5577, LF_READONLY, MFC, _SLIX, _SLIX2, _NTAG5,
|
||||
iso15_frame, iso15_flags_decode, catalog_for, catalog_for as _cf)
|
||||
from pm3py.cli.rawcli.tlv import parse_tlv, format_tlv
|
||||
from pm3py.cli.rawcli.completer import RawCompleter
|
||||
@@ -496,6 +496,21 @@ class TestCatalog:
|
||||
s.transponder = "ICODE SLIX2"; assert catalog_for(s) is _SLIX2
|
||||
s.transponder = "ICODE SLIX"; assert catalog_for(s) is _SLIX
|
||||
|
||||
def test_ntag5_catalog(self):
|
||||
# NTAG5 = SLIX2 minus STAY_QUIET_PERSISTENT (rejected), plus config / SRAM / pick-random-UID
|
||||
assert "STAY_QUIET_PERSISTENT" not in _NTAG5.commands
|
||||
assert "READ_SIGNATURE" in _NTAG5.commands # inherited from SLIX2
|
||||
for name, op in [("READ_CONFIG", 0xC0), ("WRITE_CONFIG", 0xC1), ("PICK_RANDOM_UID", 0xC2),
|
||||
("READ_SRAM", 0xD2), ("WRITE_SRAM", 0xD3)]:
|
||||
assert _NTAG5.get(name).opcode() == op
|
||||
assert _NTAG5.by_opcode(op).name == name
|
||||
assert _NTAG5.get("READ_CONFIG").build("0xA1", "1") == bytes.fromhex("02c004a100") # CONFIG_REG
|
||||
assert _NTAG5.get("WRITE_CONFIG").build("0xA1", "20000000") == bytes.fromhex("02c104a120000000")
|
||||
assert _NTAG5.get("PICK_RANDOM_UID").build() == b"\x02\xC2\x04"
|
||||
# dispatch (checked before SLIX2/SLIX): an identified NTAG5 resolves here
|
||||
s = RawSession(); s.protocol, s.transponder = "hf15", "NTAG 5"
|
||||
assert catalog_for(s) is _NTAG5
|
||||
|
||||
def test_resolver(self):
|
||||
s = RawSession()
|
||||
assert catalog_for(s) is None # nothing identified
|
||||
|
||||
Reference in New Issue
Block a user