feat(rawcli): ICODE SLIX2 datasheet catalog
SLIX2 is the SLIX command set plus three SLIX2-only commands and a larger 80-block memory: READ_SIGNATURE (0xBD, the ECC originality signature identify already probes), PASSWORD_PROTECTION_64BIT (0xBB), STAY_QUIET_PERSISTENT (0xBC). Built by reusing the SLIX catalog's commands, so it stays a strict superset; catalog_for routes an identified "ICODE SLIX2" to it (SLIX2 checked before the SLIX/ICODE fallback). Verified live through the real completer + PromptSession: command-name completion surfaces the SLIX2 commands, raw-opcode completion maps 0xBD/0xBB/0xBC back to them, and entry accepts end to end. Unit test covers the delta + dispatch. Follow-ups noted in docs/rawcli-todo.md: NTAG5 (needs a finer identify probe first, since it shares E0 04 with SLIX), and INVENTORY_READ/FAST_INVENTORY_READ for the SLIX catalogs. 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,
|
||||
from pm3py.cli.rawcli.catalog import (TYPE2, ISO15, T5577, LF_READONLY, MFC, _SLIX, _SLIX2,
|
||||
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
|
||||
@@ -458,6 +458,20 @@ class TestCatalog:
|
||||
s = RawSession(); s.protocol, s.transponder = "hf15", "ICODE SLIX"
|
||||
assert catalog_for(s) is _SLIX
|
||||
|
||||
def test_slix2_catalog(self):
|
||||
# SLIX2 = the full SLIX datasheet set plus three SLIX2-only commands (0xBD/0xBB/0xBC)
|
||||
assert set(_SLIX.commands) <= set(_SLIX2.commands) # superset of SLIX
|
||||
for name, op in [("READ_SIGNATURE", 0xBD), ("PASSWORD_PROTECTION_64BIT", 0xBB),
|
||||
("STAY_QUIET_PERSISTENT", 0xBC)]:
|
||||
assert name not in _SLIX.commands # SLIX2-only
|
||||
assert _SLIX2.get(name).opcode() == op
|
||||
assert _SLIX2.by_opcode(op).name == name # raw opcode maps back
|
||||
assert _SLIX2.get("READ_SIGNATURE").build() == b"\x02\xBD\x04" # NXP mfg inserted
|
||||
# dispatch: SLIX2 -> _SLIX2, plain SLIX still -> _SLIX (SLIX2 test comes first)
|
||||
s = RawSession(); s.protocol = "hf15"
|
||||
s.transponder = "ICODE SLIX2"; assert catalog_for(s) is _SLIX2
|
||||
s.transponder = "ICODE SLIX"; assert catalog_for(s) is _SLIX
|
||||
|
||||
def test_resolver(self):
|
||||
s = RawSession()
|
||||
assert catalog_for(s) is None # nothing identified
|
||||
|
||||
Reference in New Issue
Block a user