Files
pm3py/docs/rawcli-todo.md
michael 7b028f4ddc feat(rawcli): INVENTORY_READ / FAST_INVENTORY_READ for the SLIX catalogs
Completes the ICODE SLIX/SLIX2 datasheet command set. These fuse an inventory round
with a block read; unlike every other catalog command they need the inventory bit set
in the request flags. Added an `inventory=` option to iso15_frame (sets inventory +
single-slot, 0x26 with high rate) and both commands to _SLIX (inherited by _SLIX2),
with the mask-less body mask_len 0 | first_block | count-1 (matching the tag model's
_handle_inventory_read: first_block at data[4], num_blocks at data[5]+1).

Verified live (completer names both, opcode 0xA0/0xA1 map back, entry round-trips) and
unit-tested. Mask-based inventory (AFI/mask value) left as a future refinement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 12:56:00 -07:00

4.5 KiB

rawcli — catalog & memory-hinting roadmap

The MVP is a list of named transponders, each surfaced through the same UX: a command catalog + a datasheet memory map, both offered as autocomplete suggestions in the completion dropdown — never on the bottom bar, never in command output.

The UX contract (applies to every transponder)

  • Completion dropdown offers: command names (by letter → READ(), opcodes (by hex/binary value → raw byte inserted, command as the label), and page/block landmarks with datasheet roles.
  • Must work in both hex AND binary entry modes, rendering in the active base.
  • Function-call args are base-10 (READ(4)); raw bytes are hex, 0b to intermix binary.

FIXED — raw byte-line autocomplete now fires in hex AND binary

Root cause: entry._digit applied each keystroke as buf.document = Document(...), which resets prompt_toolkit's complete_state and never re-fires completion — so the live menu never appeared during raw byte entry. This hit both hex and binary (the earlier "hex works, binary doesn't" was inaccurate; only command-name completion worked, because that path already used insert_text). Fixed by appending the per-keystroke delta via buf.insert_text instead — type_digit only ever appends (optionally after an auto-space) or drops, so the change is always a pure suffix, and insert_text triggers completion exactly like an ordinary keystroke. Verified by driving the real key handler: the menu now populates on every digit in both modes. Regression: TestKeyBindings::test_digit_binding_fires_completion_trigger_for_raw_bytes.

The Ctrl-t / Ctrl-_ toggle correctly flips the breadcrumb 0x <-> 0b and requests a redraw (verified, guarded by test_toggle_updates_breadcrumb_prefix). An end-to-end live-session test (TestRawcliLiveSession) drives the real PromptSession via a pipe input. A human eyeball of the rendered dropdown on a real terminal is the only thing left unautomated.

Priority 1 — MIFARE Classic (do this first)

  • Identify: distinguish 1K (SAK 0x08) / 4K (0x18) / Mini (0x09); today only named, no map.
  • Memory map (block → role), mirroring the NTAG page map:
    • Block 0 = manufacturer block: UID + BCC + SAK + ATQA + manufacturer data.
    • Sector trailer (block 3,7,…,63 on 1K; last block of each sector on 4K): Key A (0-5), access bits (6-8) + GPB (9), Key B (10-15) — the access bits are the bit-level detail.
    • Other blocks = data block (with sector number).
    • 4K: sectors 0-31 are 4 blocks; sectors 32-39 are 16 blocks each.
  • Catalog: READ/WRITE/HALT exist; note that reads/writes need prior AUTH (Key A/B) — the authenticate step is the reader's job before these.
  • Autocomplete must work in hex + binary (see the bug above).

After MFC — 15693 vicinity chips: ICODE SLIX , ICODE SLIX2 , NTAG5 (next)

  1. 15693 header builder iso15_frame() (flags + command + NXP mfg 0x04), shared by all 15693 catalogs.
  2. Per-chip identifyidentify.name_iso15 distinguishes SLIX vs SLIX2 (READ_SIGNATURE 0xBD probe). NTAG5 and ICODE DNA still fall through to "ICODE SLIX" (they share E0 04); NTAG5 needs a finer probe (IC-reference / GET_SYSTEM_INFO) before its catalog can be routed.
  3. Catalogs_SLIX (plain) and _SLIX2 (_SLIX + READ_SIGNATURE 0xBD / PASSWORD_PROTECTION_64BIT 0xBB / STAY_QUIET_PERSISTENT 0xBC, 80 blocks) done, dispatched by catalog_for, verified live. NTAG5 catalog (READ/WRITE_CONFIG, the NTAG5 config registers, password/AES) still to build — source from transponders/hf/iso15693/nxp/ntag5_*.
  4. Autocomplete UX (hex + binary, command names + opcode-by-value; the byte-line completion bug is fixed).

INVENTORY_READ (0xA0) / FAST_INVENTORY_READ (0xA1) — added to _SLIX (and inherited by _SLIX2) with the inventory flags (0x26) + mask-less body (mask_len 0 | first_block | count-1) via a new inventory= option on iso15_frame. Mask-based inventory (AFI/mask value) is a further refinement if ever needed.

Hardware verify pending: SLIX2 catalog was verified only against unit tests + a live-session drive (no SLIX2 tag on the reader). Confirm on a real SLIX2 when one is available.

Also queued

  • T5577 config block (block 0) bitfield decode (modulation, bit-rate, block count, PWD/AOR) — currently just "config block".
  • NTAG I2C plus (model exists, identify names it) — catalog + map.

See project_rawcli_mvp in memory for the named-transponder scope.