feat(rawcli): interactive raw-command TUI skeleton (Phase 1)
First slice of `pm3py rawcli` — the interactive, annotated raw-command tool (separate from pyws and from the future `pm3py client` CLI). - pm3py/cli: a top-level `pm3py` console-script dispatcher (argparse) with a `rawcli` subcommand; prompt_toolkit gated behind a [rawcli] extra - rawcli/session.py: RawSession — device/field/transponder/entry-mode state + the segmented breadcrumb `[raw / hf|lf / $tag / 0x|0b]` - rawcli/trace_view.py: render a reader<->tag exchange as annotated, Proxmark-style trace lines, reusing TraceFormatter + the 14a/15693 decoders - rawcli/app.py: minimal PromptSession loop (connect best-effort, breadcrumb prompt, help/quit, raw-hex -> annotated exchange) Entry-mode toggle, identify/connection, the command catalog, and TLV editing follow in later phases. 9 hardware-free tests (session, trace render, CLI dispatch); device I/O is the user's local hardware test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
24
pm3py/cli/rawcli/trace_view.py
Normal file
24
pm3py/cli/rawcli/trace_view.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""Render a raw reader↔tag exchange as annotated, Proxmark-style trace lines, reusing the
|
||||
existing :class:`pm3py.trace.TraceFormatter` and the per-protocol decoders."""
|
||||
from __future__ import annotations
|
||||
|
||||
from pm3py.trace import TraceFormatter, decode_14443a, decode_15693
|
||||
|
||||
#: protocol key -> (annotation decoder, CRC byte length)
|
||||
_PROTOCOLS = {
|
||||
"hf14a": (decode_14443a, 2),
|
||||
"hf15": (decode_15693, 2),
|
||||
"lf": (None, 0),
|
||||
}
|
||||
|
||||
|
||||
def render_exchange(command: bytes, response: bytes | None, *,
|
||||
protocol: str = "hf14a", is_tty: bool | None = None) -> str:
|
||||
"""Return the annotated trace for one exchange: a ``Reader → Tag`` line for ``command`` and,
|
||||
if present, a ``Tag → Reader`` line for ``response``. ``is_tty`` forces/suppresses ANSI."""
|
||||
decoder, crc_len = _PROTOCOLS.get(protocol, (None, 0))
|
||||
fmt = TraceFormatter(mode="reader", decoder=decoder, crc_len=crc_len, is_tty=is_tty)
|
||||
lines = [fmt.format(0, bytes(command)).lstrip("\n")]
|
||||
if response:
|
||||
lines.append(fmt.format(1, bytes(response)).lstrip("\n"))
|
||||
return "\n".join(lines)
|
||||
Reference in New Issue
Block a user