- identify.py: probe HF (14a -> 15693) then LF; set session field / protocol / transponder. The 14a scan uses NO_DISCONNECT so the tag stays selected (the persistent connection). SAK -> coarse family name for the breadcrumb. - session: add `protocol` (drives raw-exchange routing) - app: connect via Proxmark3.sync() (scan/raw become plain calls); wire identify / transponder / close control commands; protocol-aware _raw_exchange; breadcrumb fills in field + transponder after identify 8 new tests (identify 14a/15693/none, clear, control commands). Device probes are mocked; live identify is the user's hardware test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
46 lines
1.7 KiB
Python
46 lines
1.7 KiB
Python
"""rawcli session state — the connected device, the identified RF field and transponder, and
|
|
the current numeric entry mode. Kept deliberately small and free of any prompt_toolkit / device
|
|
detail so it stays unit-testable."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
HEX = "hex"
|
|
BIN = "bin"
|
|
|
|
|
|
class RawSession:
|
|
"""Mutable rawcli session state.
|
|
|
|
``device`` is the connected client (or ``None`` when offline). ``field`` is the identified RF
|
|
field (``"hf"``/``"lf"``) and ``transponder`` the identified tag's display name — both set by
|
|
``identify`` in a later phase. ``entry_mode`` is the numeric entry mode toggled by the user.
|
|
"""
|
|
|
|
def __init__(self, device: Any = None):
|
|
self.device = device
|
|
self.field: str | None = None
|
|
self.transponder: str | None = None
|
|
self.protocol: str = "hf14a" # wire protocol for raw exchanges (set by identify)
|
|
self.entry_mode: str = HEX
|
|
self.connected: bool = device is not None
|
|
|
|
@property
|
|
def entry_prefix(self) -> str:
|
|
return "0x" if self.entry_mode == HEX else "0b"
|
|
|
|
def toggle_entry_mode(self) -> str:
|
|
self.entry_mode = BIN if self.entry_mode == HEX else HEX
|
|
return self.entry_mode
|
|
|
|
def breadcrumb(self) -> str:
|
|
"""The segmented prompt ``[raw / <field?> / <transponder?> / 0x|0b]`` — field and
|
|
transponder segments appear only once identified."""
|
|
segments = ["raw"]
|
|
if self.field:
|
|
segments.append(self.field)
|
|
if self.transponder:
|
|
segments.append(self.transponder)
|
|
segments.append(self.entry_prefix)
|
|
return "[" + " / ".join(segments) + "]"
|