feat(rawcli): annotate read/write output with datasheet memory regions
A READ now names the memory locations the pages cover, per the tag's datasheet layout, grouping consecutive same-role pages: READ(0) -> 00-02 → UID / serial number · 03 → Capability Container (CC) READ(4) -> 04-07 → user memory READ(0xE3) -> E3 → CFG0 · E4 → CFG1 · E5 → PWD · E6 → PACK TagCommand gains a pages() callable (which page/block numbers a command touches: READ = 4 pages from <page>, FAST_READ = <start>..<end>, WRITE = one page). memory.region_annotation() groups those into "lo-hi → role" via the existing page_role layouts; _handle_call prints it after the exchange. No layout for the tag (e.g. MIFARE Classic) -> no annotation. Hardware-verified on NTAG216 (READ 0/4/0xE3, FAST_READ). Tests for the grouping + the dispatch path. 1264 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -392,6 +392,21 @@ class TestFunctionCalls:
|
||||
assert calls[0].args[0] == b"\xA0\x04"
|
||||
assert calls[1].args[0] == b"\x01\x02\x03\x04" + b"\x00" * 12
|
||||
|
||||
def test_read_annotates_memory_region(self, capsys):
|
||||
# READ output names the datasheet regions the pages cover (the user's ask)
|
||||
s = RawSession(device=_mock_device(
|
||||
scan14={"found": True, "sak": 0x00, "atqa": "4400", "uid": "04a1b2c3d4e5f6"},
|
||||
version=NTAG216_VERSION))
|
||||
dispatch(s, "identify")
|
||||
assert s.transponder == "NTAG216"
|
||||
s.device.hf.iso14a.raw.return_value = {"raw": b"\x03\x00\xFE\x00" * 4}
|
||||
capsys.readouterr()
|
||||
dispatch(s, "READ(4)")
|
||||
assert "04-07 → user memory" in _plain(capsys.readouterr().out)
|
||||
dispatch(s, "READ(0)")
|
||||
o = _plain(capsys.readouterr().out)
|
||||
assert "UID / serial number" in o and "Capability Container" in o
|
||||
|
||||
def test_call_without_identify(self, capsys):
|
||||
dispatch(RawSession(), "READ(4)")
|
||||
assert "identify" in capsys.readouterr().out
|
||||
@@ -524,6 +539,15 @@ class TestMemoryHint:
|
||||
from pm3py.cli.rawcli.memory import input_hint
|
||||
assert input_hint(RawSession(), "READ(4)") is None
|
||||
|
||||
def test_region_annotation(self):
|
||||
from pm3py.cli.rawcli.memory import region_annotation
|
||||
assert region_annotation("NTAG216", [0, 1, 2, 3]) == \
|
||||
"00-02 → UID / serial number · 03 → Capability Container (CC)"
|
||||
assert region_annotation("NTAG216", [4, 5, 6, 7]) == "04-07 → user memory"
|
||||
assert "PWD" in region_annotation("NTAG213", [0x2B])
|
||||
assert region_annotation("MIFARE Classic 1K", [4]) is None # no layout -> no annotation
|
||||
assert region_annotation("NTAG216", []) is None
|
||||
|
||||
def test_t5577_block_roles(self):
|
||||
from pm3py.cli.rawcli.memory import page_role, input_hint
|
||||
tp = "T5577 (EM4100 20260716FF)"
|
||||
|
||||
Reference in New Issue
Block a user