Commit Graph

28 Commits

Author SHA1 Message Date
michael
137ec1e721 feat(iso15): add inventory() with 1/16-slot parsing + AFI/DSFID filtering
inventory() parses both response formats: slots=1 -> single tag dict (or None); slots=16 -> list of tags from the iso15_inventory_response_t anti-collision struct, each CRC15-validated. Optional request-level AFI filter and client-side DSFID filter. One 16-slot round drops colliding slots (full tree-walk resolution is a follow-up); scan() stays the single-tag convenience.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 00:34:15 -07:00
michael
739e28e113 feat(client): make dir()/help() work through _SyncProxy
The sync REPL proxy forwarded methods via __getattr__, so dir()/tab-completion never saw them and the sync wrapper reported (*args, **kwargs) instead of the real signature. Add __dir__ delegating to the wrapped target, and decorate the async wrapper with functools.wraps so inspect.signature()/help() report the real params + docstring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 00:20:03 -07:00
michael
a90a01f2aa fix(lf): correct T55xx write/wakeup structs, 2-byte LF tune, fire-and-forget sampling config
lf.tune sends the 2-byte {mode,divisor} the firmware requires (was 3 -> EINVARG/0V). t55.writebl packs the 10-byte {data,pwd,blockno,flags} struct with a single bit-packed flags byte (was 12). t55.wakeup packs 5 bytes {pwd,flags}. t55.config is maintained client-side (firmware has no GET). LF_SAMPLING_SET_CONFIG uses send_ng_no_response (firmware never replies). Pre-existing, independent of the rebase.
2026-07-05 00:10:31 -07:00
michael
820701511c fix(14a): NG struct for sim (+ tagtype, enables MFU/NTAG sim), NG for sniff
14a.sim sent a MIX frame but the handler is NG casting a packed {tagtype,u16 flags,uid[10],exitAfter,rats[20],ulauth...} struct -> whole struct garbled, flags never arrived. Rewrite to send_ng with the exact struct and expose tagtype (2=Ultralight,7=NTAG) so Ultralight/NTAG sim works. 14a.sniff sent MIX (args stripped -> empty asBytes); send NG with the 1-byte param. Pre-existing, independent of rebase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 00:08:40 -07:00
michael
3d4634a406 fix(hf,hw): fire-and-forget dropfield, full HF_SNIFF struct, standalone payload
dropfield waited on a reply the firmware never sends (bare hf_field_off();break;) -> 2s stall + raise; use send_ng_no_response. hf.sniff under-sent the 10-byte {u32,u32,u8,u8} struct and mis-parsed the uint16 reply. hw.standalone sent an empty payload for a {arg,mlen,mode[10]} struct and blocked; pack it + fire-and-forget. Pre-existing, independent of rebase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 00:08:40 -07:00
michael
625104ea03 fix(mfc): correct WRITEBL offset, NESTED struct order, CIDENT/SIM payloads; route sniff to 14a
wrbl padded key to 16 (firmware reads block at asBytes+10) -> corrupt writes; pad to 10. nested sent {block,keytype,key,target...} but firmware struct is {block,keytype,target_block,target_keytype,calibrate,key[6]} -> attacked wrong target; reorder + add calibrate + decode reply. cident/sim sent empty/MIX payloads for NG handlers -> send the packed structs. mf.sniff (no firmware handler) reroutes to CMD_HF_ISO14443A_SNIFF. Pre-existing, independent of rebase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 00:08:40 -07:00
michael
f2b23f768b fix(iso15): correct transport flags + append CRC host-side (scan/rdbl/wrbl)
ISO15_READ_RESPONSE was 0x10 but the firmware bit is 0x20 (0x10 is HIGH_SPEED, which pm3py lacked), so scan/rdbl/wrbl sent flags 0x19 with READ_RESPONSE never set -> firmware never listened and replied empty. The ARM firmware also ignores ISO15_APPEND_CRC (the C client adds the CRC host-side via AddCrc15), so pm3py's CRC-less frames were never answered by a real tag.

Fix flag values to match firmware include/iso15.h, add crc15 (CRC-16/X-25), and route all iso15 commands through _iso15_payload (appends CRC, sends CONNECT|HIGH_SPEED|READ_RESPONSE=0x31). Payload now byte-matches the C client getUID. Pre-existing bug, independent of the firmware rebase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 22:48:23 -07:00
michael
35f16b7664 fix(hf): tune() must send START/MEASURE/STOP mode byte and parse uint16
CMD_MEASURE_ANTENNA_TUNING_HF requires a 1-byte mode arg (firmware rejects length!=1 with EINVARG) and returns the voltage as uint16, not uint32. tune() sent no arg (empty reply -> 0 mV) and parsed <I. Now sends mode 1/2/3 (START/MEASURE/STOP) and parses <H. Verified vs firmware appmain.c handler; C client reads the same ~15V on this firmware.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 22:38:23 -07:00
michael
83c8dd5546 test: comprehensive SniffSession live streaming tests
10 tests covering streaming flags, trace entry parsing, status
transitions, button-toggle lifecycle, BREAK_LOOP, entry accumulation
across pause/resume cycles, and full end-to-end workflow.
2026-03-19 12:34:10 -07:00
michael
c1ab980036 refactor: remove all backward-compat shims from sim/
Deletes 24 shim files from sim/. All test imports now point directly
to canonical transponders/ and trace/ paths. sim/ contains only
infrastructure (15 files): frame, memory, transponder ABC, reader ABC,
medium, sim_session, table_compiler, replay, relay, fuzzer, pm3medium,
mcu_bridge, mcu_protocol, dual_session, __init__.

751 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 20:56:40 -07:00
michael
8e8b945246 refactor: unify sim/trace_fmt.py into trace/ package
Merges the richer sim trace formatter into the shared trace/ package:
- trace/decode_iso14a.py — new, 14443-A request/response decoders
- trace/decode_iso15.py — enhanced with NXP annotations, IC identification,
  GET SYSTEM INFO parsing, decode_15693_nxp()
- trace/format.py — TraceFormatter class (mode-aware, CRC handling,
  SIGWINCH resize) + format_sniff_line convenience wrapper
- sim/trace_fmt.py → backward compat shim importing from trace/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 20:47:01 -07:00
michael
668170457e feat: migrate sim framework from worktree to master
Migrates all 43 sim modules and 23 test files (~7.8k LOC, 686 tests)
from .worktrees/sim-framework/ into pm3py/sim/. Import fixes:
- 4 files: ..protocol/..transport → ..core.protocol/..core.transport
- trace_fmt.py: pm3py.hf_15 → pm3py.trace.ndef
- test_sim_pm3medium.py: flat imports → core.*
- test_sim_trace_fmt.py: flat imports → core.*
- Added sim Cmd entries to core/protocol.py (EML_SETMEM, SIM_TABLE_*)

751 tests passing (686 sim + 65 core).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 20:04:55 -07:00
michael
ff8c5d4e73 Merge branch 'refactor/core-package' into master
Merges the package refactor (core/ sub-package, normalized naming,
scaffolded sub-packages) while preserving all in-progress sniff
infrastructure. Git rename detection carried WIP changes to new paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:34:48 -07:00
michael
ca3d4bf31b WIP: sniff infrastructure, transport additions, test coverage
In-progress work — committing before refactor merge so git rename
detection can carry changes to new file locations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:33:10 -07:00
michael
42e6b54f29 refactor: move modules into core/ sub-package, normalize naming
Phase 1 of package refactor. Moves all source modules into pm3py/core/
with file renames (hf_14a→hf_iso14a, hf_15→hf_iso15, hf_mf→hf_mfc)
and client attribute normalization (hf.a14→hf.iso14a, hf.mf→hf.mfc).
pm3py/__init__.py re-exports from core for backward compat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:24:05 -07:00
michael
a91d862647 fix(pm3py): platform-aware LED color mapping (Easy vs RDV4 have different physical layouts) 2026-03-16 00:22:43 -07:00
michael
cc7dfa89de feat(pm3py): validate PWM LED capability using device capabilities, raise on non-PWM LEDs 2026-03-16 00:20:47 -07:00
michael
8cce7eeba3 feat(pm3py): LED API with color names and keyword actions (on/off/pulse/fade/blink/brightness) 2026-03-16 00:13:50 -07:00
michael
205e9b7993 feat(pm3py): add Proxmark3.sync() for REPL/script usage without async boilerplate 2026-03-16 00:09:14 -07:00
michael
c015082b41 fix(pm3py): disable CRC for USB (matching C client), fix CRC byte order for FPC UART 2026-03-16 00:03:23 -07:00
michael
d9ec661d06 feat(pm3py): soft firmware compatibility check on connect (ping + version probe) 2026-03-15 22:25:37 -07:00
michael
fec04acc23 feat(pm3py): integration tests and final API wiring 2026-03-15 22:19:00 -07:00
michael
31a6036cd3 feat(pm3py): ISO15693 + MIFARE Classic commands 2026-03-15 22:18:11 -07:00
michael
2f88fabde6 feat(pm3py): HF core + ISO14443A commands 2026-03-15 22:16:54 -07:00
michael
95133843a4 feat(pm3py): LF commands (tune, read, sniff, sim, config, search, t55xx) 2026-03-15 22:15:51 -07:00
michael
10761b1d5f feat(pm3py): client shell and hw commands (ping, version, status, led, tune, etc) 2026-03-15 22:14:12 -07:00
michael
03569d2361 feat(pm3py): transport layer with NG/MIX frame encoding and async serial I/O 2026-03-15 22:12:53 -07:00
michael
22dc438464 feat(pm3py): project scaffolding with CRC-16/A and protocol constants 2026-03-15 22:11:38 -07:00