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>
This commit is contained in:
74
docs/plans/2026-03-18-refactor-progress.md
Normal file
74
docs/plans/2026-03-18-refactor-progress.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# pm3py Refactor Progress
|
||||||
|
|
||||||
|
**Design:** [2026-03-18-refactor-design.md](2026-03-18-refactor-design.md)
|
||||||
|
**Branch:** `refactor/core-package`
|
||||||
|
**Started:** 2026-03-18
|
||||||
|
|
||||||
|
## Phase 1 — Create `core/`, normalize names, fix imports
|
||||||
|
|
||||||
|
**Status: Complete**
|
||||||
|
|
||||||
|
### What was done
|
||||||
|
|
||||||
|
- Created `pm3py/core/` sub-package
|
||||||
|
- Moved all source modules into `core/`:
|
||||||
|
- `protocol.py`, `transport.py`, `client.py`, `hw.py`, `hf.py`, `lf.py` — moved as-is
|
||||||
|
- `hf_14a.py` → `hf_iso14a.py` (renamed)
|
||||||
|
- `hf_15.py` → `hf_iso15.py` (renamed)
|
||||||
|
- `hf_mf.py` → `hf_mfc.py` (renamed)
|
||||||
|
- Normalized client attributes:
|
||||||
|
- `hf.a14` → `hf.iso14a`
|
||||||
|
- `hf.mf` → `hf.mfc`
|
||||||
|
- `hf.iso15` — unchanged
|
||||||
|
- Created `core/__init__.py` re-exporting: `Proxmark3`, `FirmwareInfo`, `PM3Transport`, `PM3Error`, `PM3Response`, `PM3Status`, `Cmd`
|
||||||
|
- Updated `pm3py/__init__.py` to import from `.core.*`
|
||||||
|
- Updated all 10 test files (imports + attribute references)
|
||||||
|
- **30/30 tests passing**
|
||||||
|
|
||||||
|
### Backward compatibility
|
||||||
|
|
||||||
|
- `from pm3py import Proxmark3` still works (re-exported)
|
||||||
|
- **Breaking:** `hf.a14` → `hf.iso14a`, `hf.mf` → `hf.mfc`
|
||||||
|
- **Breaking:** Direct imports like `from pm3py.hf_14a import ...` → `from pm3py.core.hf_iso14a import ...`
|
||||||
|
|
||||||
|
## Phase 2 — Extract `sniff/`
|
||||||
|
|
||||||
|
**Status: Scaffolded — extraction deferred**
|
||||||
|
|
||||||
|
`hf_iso15.py` is 94 lines of clean reader commands + thin `sniff()` firmware call. The trace parsing, 15693 decoders, NDEF annotation, and ANSI formatting described in the design doc haven't been written yet. Nothing to extract.
|
||||||
|
|
||||||
|
Created `pm3py/sniff/__init__.py` placeholder. Will extract into sub-modules when sniff infrastructure is implemented.
|
||||||
|
|
||||||
|
## Phase 3 — Scaffold `transponders/`
|
||||||
|
|
||||||
|
**Status: Complete (scaffolded)**
|
||||||
|
|
||||||
|
Created full directory tree per design:
|
||||||
|
- `transponders/hf/iso14443a3/nxp/` — MIFARE Classic, Ultralight, NTAG
|
||||||
|
- `transponders/hf/iso14443a4/nxp/` — DESFire, NTAG 5
|
||||||
|
- `transponders/hf/iso15693/nxp/` — ICODE SLIX2
|
||||||
|
- `transponders/hf/iso15693/st/` — ST25TV
|
||||||
|
- `transponders/lf/atmel/` — T55xx
|
||||||
|
- `transponders/lf/em/` — EM4100, EM4x05
|
||||||
|
|
||||||
|
All directories have `__init__.py`. Model migration from sim worktree is a separate effort — the sim framework has ~7.8k LOC with deep inheritance chains (`Transponder` → `Tag15693` → `NxpIcodeTag` → `IcodeSlix2Tag`, etc.) and auth mixins (`NxpPasswordAuth`, `NxpAesAuth`). Base class extraction needs to happen alongside model migration.
|
||||||
|
|
||||||
|
## Phase 4 — Scaffold `reader/` and `sim/`
|
||||||
|
|
||||||
|
**Status: Complete (scaffolded)**
|
||||||
|
|
||||||
|
Created directory trees per design:
|
||||||
|
- `reader/hf/nxp/` — NXP reader ICs (CLRC663, PN5xx)
|
||||||
|
- `reader/hf/st/` — ST reader ICs
|
||||||
|
- `reader/lf/`
|
||||||
|
- `reader/modes/` — inventory, programming, access control workflows
|
||||||
|
- `sim/` — sim session, table compiler, relay (migrate from worktree)
|
||||||
|
|
||||||
|
All directories have `__init__.py`. Sim migration (~41 files, 7.8k LOC) is a separate effort.
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- Sniff infrastructure: implement trace parsing, 15693 decoders, NDEF annotation, ANSI formatting in `sniff/`
|
||||||
|
- Transponder migration: extract base classes from sim worktree, populate `transponders/` modules
|
||||||
|
- Sim migration: move sim session, table compiler, relay into `sim/`
|
||||||
|
- Reader modes: implement inventory, programming, access workflows in `reader/modes/`
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
"""pm3py - Python wire protocol library for Proxmark3."""
|
"""pm3py - Python wire protocol library for Proxmark3."""
|
||||||
from .client import Proxmark3
|
from .core.client import Proxmark3
|
||||||
from .transport import PM3Error, PM3Response
|
from .core.transport import PM3Error, PM3Response
|
||||||
from .protocol import PM3Status, Cmd
|
from .core.protocol import PM3Status, Cmd
|
||||||
|
|
||||||
__all__ = ["Proxmark3", "PM3Error", "PM3Response", "PM3Status", "Cmd"]
|
__all__ = ["Proxmark3", "PM3Error", "PM3Response", "PM3Status", "Cmd"]
|
||||||
|
|||||||
10
pm3py/core/__init__.py
Normal file
10
pm3py/core/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
"""pm3py.core — Wire protocol, transport, and device commands."""
|
||||||
|
from .client import Proxmark3, FirmwareInfo
|
||||||
|
from .transport import PM3Transport, PM3Error, PM3Response
|
||||||
|
from .protocol import PM3Status, Cmd
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Proxmark3", "FirmwareInfo",
|
||||||
|
"PM3Transport", "PM3Error", "PM3Response",
|
||||||
|
"PM3Status", "Cmd",
|
||||||
|
]
|
||||||
@@ -10,9 +10,9 @@ from .transport import PM3Transport, PM3Response, PM3Error, ProgressCallback
|
|||||||
from .hw import HWCommands
|
from .hw import HWCommands
|
||||||
from .lf import LFCommands
|
from .lf import LFCommands
|
||||||
from .hf import HFCommands
|
from .hf import HFCommands
|
||||||
from .hf_14a import HF14ACommands
|
from .hf_iso14a import HF14ACommands
|
||||||
from .hf_15 import HF15Commands
|
from .hf_iso15 import HF15Commands
|
||||||
from .hf_mf import HFMFCommands
|
from .hf_mfc import HFMFCommands
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -68,9 +68,9 @@ class Proxmark3:
|
|||||||
self.hw = HWCommands(self._transport)
|
self.hw = HWCommands(self._transport)
|
||||||
self.lf = LFCommands(self._transport)
|
self.lf = LFCommands(self._transport)
|
||||||
self.hf = HFCommands(self._transport)
|
self.hf = HFCommands(self._transport)
|
||||||
self.hf.a14 = HF14ACommands(self._transport)
|
self.hf.iso14a = HF14ACommands(self._transport)
|
||||||
self.hf.iso15 = HF15Commands(self._transport)
|
self.hf.iso15 = HF15Commands(self._transport)
|
||||||
self.hf.mf = HFMFCommands(self._transport)
|
self.hf.mfc = HFMFCommands(self._transport)
|
||||||
self.firmware = FirmwareInfo()
|
self.firmware = FirmwareInfo()
|
||||||
|
|
||||||
async def connect(self) -> None:
|
async def connect(self) -> None:
|
||||||
@@ -157,7 +157,7 @@ class _SyncProxy:
|
|||||||
if isinstance(attr, (HWCommands, LFCommands, HFCommands,
|
if isinstance(attr, (HWCommands, LFCommands, HFCommands,
|
||||||
HF14ACommands, HF15Commands, HFMFCommands)):
|
HF14ACommands, HF15Commands, HFMFCommands)):
|
||||||
return _SyncProxy(attr, self._loop)
|
return _SyncProxy(attr, self._loop)
|
||||||
# Sub-modules attached dynamically (e.g. hf.a14, hf.mf)
|
# Sub-modules attached dynamically (e.g. hf.iso14a, hf.mfc)
|
||||||
if hasattr(attr, '_t'):
|
if hasattr(attr, '_t'):
|
||||||
return _SyncProxy(attr, self._loop)
|
return _SyncProxy(attr, self._loop)
|
||||||
if callable(attr) and inspect.iscoroutinefunction(attr):
|
if callable(attr) and inspect.iscoroutinefunction(attr):
|
||||||
@@ -11,9 +11,9 @@ class HFCommands:
|
|||||||
def __init__(self, transport: PM3Transport):
|
def __init__(self, transport: PM3Transport):
|
||||||
self._t = transport
|
self._t = transport
|
||||||
# Sub-modules attached by client.py
|
# Sub-modules attached by client.py
|
||||||
self.a14 = None # type: ignore
|
self.iso14a = None # type: ignore
|
||||||
self.iso15 = None # type: ignore
|
self.iso15 = None # type: ignore
|
||||||
self.mf = None # type: ignore
|
self.mfc = None # type: ignore
|
||||||
|
|
||||||
async def tune(self, on_progress: ProgressCallback = None) -> dict:
|
async def tune(self, on_progress: ProgressCallback = None) -> dict:
|
||||||
"""Measure HF antenna voltage."""
|
"""Measure HF antenna voltage."""
|
||||||
@@ -38,9 +38,9 @@ class HFCommands:
|
|||||||
if asyncio.iscoroutine(ret):
|
if asyncio.iscoroutine(ret):
|
||||||
await ret
|
await ret
|
||||||
|
|
||||||
if self.a14:
|
if self.iso14a:
|
||||||
try:
|
try:
|
||||||
card = await self.a14.scan()
|
card = await self.iso14a.scan()
|
||||||
if card.get("uid"):
|
if card.get("uid"):
|
||||||
results["iso14443a"] = card
|
results["iso14443a"] = card
|
||||||
except PM3Error:
|
except PM3Error:
|
||||||
1
pm3py/reader/__init__.py
Normal file
1
pm3py/reader/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""pm3py.reader — Higher-level reader modes composing core commands."""
|
||||||
1
pm3py/reader/hf/__init__.py
Normal file
1
pm3py/reader/hf/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""HF reader modes organized by reader IC manufacturer."""
|
||||||
1
pm3py/reader/hf/nxp/__init__.py
Normal file
1
pm3py/reader/hf/nxp/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""NXP reader ICs (CLRC663, PN5xx)."""
|
||||||
1
pm3py/reader/hf/st/__init__.py
Normal file
1
pm3py/reader/hf/st/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""ST Microelectronics reader ICs."""
|
||||||
1
pm3py/reader/lf/__init__.py
Normal file
1
pm3py/reader/lf/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""LF reader modes."""
|
||||||
1
pm3py/reader/modes/__init__.py
Normal file
1
pm3py/reader/modes/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""Reader workflow modes — inventory, programming, access control."""
|
||||||
1
pm3py/sim/__init__.py
Normal file
1
pm3py/sim/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""pm3py.sim — Card simulation sessions, table compiler, relay."""
|
||||||
1
pm3py/sniff/__init__.py
Normal file
1
pm3py/sniff/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""pm3py.sniff — Sniff sessions, trace parsing, protocol decoders, formatting."""
|
||||||
1
pm3py/transponders/__init__.py
Normal file
1
pm3py/transponders/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""pm3py.transponders — Tag/transponder models independent of hardware."""
|
||||||
1
pm3py/transponders/hf/__init__.py
Normal file
1
pm3py/transponders/hf/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""HF transponder models organized by ISO standard, then manufacturer."""
|
||||||
1
pm3py/transponders/hf/iso14443a3/__init__.py
Normal file
1
pm3py/transponders/hf/iso14443a3/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""ISO 14443-A Layer 3 transponders (MIFARE Classic, Ultralight, NTAG)."""
|
||||||
1
pm3py/transponders/hf/iso14443a3/nxp/__init__.py
Normal file
1
pm3py/transponders/hf/iso14443a3/nxp/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""NXP ISO 14443-A Layer 3 transponders."""
|
||||||
1
pm3py/transponders/hf/iso14443a4/__init__.py
Normal file
1
pm3py/transponders/hf/iso14443a4/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""ISO 14443-A Layer 4 (ISO-DEP) transponders (DESFire, NTAG 5 via -4)."""
|
||||||
1
pm3py/transponders/hf/iso14443a4/nxp/__init__.py
Normal file
1
pm3py/transponders/hf/iso14443a4/nxp/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""NXP ISO 14443-A Layer 4 transponders."""
|
||||||
1
pm3py/transponders/hf/iso15693/__init__.py
Normal file
1
pm3py/transponders/hf/iso15693/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""ISO 15693 transponder models and NFC Forum Type 5 NDEF."""
|
||||||
1
pm3py/transponders/hf/iso15693/nxp/__init__.py
Normal file
1
pm3py/transponders/hf/iso15693/nxp/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""NXP ICODE / NTAG 5 ISO 15693 transponders."""
|
||||||
1
pm3py/transponders/hf/iso15693/st/__init__.py
Normal file
1
pm3py/transponders/hf/iso15693/st/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""ST Microelectronics ISO 15693 transponders."""
|
||||||
1
pm3py/transponders/lf/__init__.py
Normal file
1
pm3py/transponders/lf/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""LF transponder models organized by manufacturer."""
|
||||||
1
pm3py/transponders/lf/atmel/__init__.py
Normal file
1
pm3py/transponders/lf/atmel/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""Atmel/Microchip LF transponders (T55xx)."""
|
||||||
1
pm3py/transponders/lf/em/__init__.py
Normal file
1
pm3py/transponders/lf/em/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""EM Microelectronic LF transponders (EM4100, EM4x05)."""
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
from pm3py.protocol import crc16_a
|
from pm3py.core.protocol import crc16_a
|
||||||
|
|
||||||
def test_crc16_a_empty():
|
def test_crc16_a_empty():
|
||||||
assert crc16_a(b"") == 0x6363 # init 0xC6C6 reflected = 0x6363
|
assert crc16_a(b"") == 0x6363 # init 0xC6C6 reflected = 0x6363
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
from pm3py.protocol import Cmd
|
from pm3py.core.protocol import Cmd
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
from pm3py.hf import HFCommands
|
from pm3py.core.hf import HFCommands
|
||||||
|
|
||||||
def test_hf_tune():
|
def test_hf_tune():
|
||||||
t = AsyncMock()
|
t = AsyncMock()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import struct
|
import struct
|
||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
from pm3py.protocol import Cmd
|
from pm3py.core.protocol import Cmd
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
from pm3py.hf_14a import HF14ACommands
|
from pm3py.core.hf_iso14a import HF14ACommands
|
||||||
|
|
||||||
def test_14a_scan():
|
def test_14a_scan():
|
||||||
t = AsyncMock()
|
t = AsyncMock()
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import struct
|
import struct
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
from pm3py.protocol import Cmd
|
from pm3py.core.protocol import Cmd
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
from pm3py.hf_15 import (
|
from pm3py.core.hf_iso15 import (
|
||||||
HF15Commands, parse_tracelog, TRACELOG_HDR_SIZE,
|
HF15Commands, parse_tracelog, TRACELOG_HDR_SIZE,
|
||||||
decode_15693_request, decode_15693_response, decode_15693,
|
decode_15693_request, decode_15693_response, decode_15693,
|
||||||
format_sniff_line, decode_ndef_annotation,
|
format_sniff_line, decode_ndef_annotation,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_15_scan():
|
def test_15_scan():
|
||||||
t = AsyncMock()
|
t = AsyncMock()
|
||||||
iso15 = HF15Commands(t)
|
iso15 = HF15Commands(t)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import struct
|
import struct
|
||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
from pm3py.protocol import Cmd
|
from pm3py.core.protocol import Cmd
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
from pm3py.hf_mf import HFMFCommands
|
from pm3py.core.hf_mfc import HFMFCommands
|
||||||
|
|
||||||
def test_mf_rdbl():
|
def test_mf_rdbl():
|
||||||
t = AsyncMock()
|
t = AsyncMock()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import struct
|
import struct
|
||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
from pm3py.protocol import Cmd
|
from pm3py.core.protocol import Cmd
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
from pm3py.hw import HWCommands
|
from pm3py.core.hw import HWCommands
|
||||||
|
|
||||||
def make_ng_response(cmd: int, status: int, payload: bytes) -> PM3Response:
|
def make_ng_response(cmd: int, status: int, payload: bytes) -> PM3Response:
|
||||||
return PM3Response(cmd=cmd, status=status, reason=0, ng=True, data=payload)
|
return PM3Response(cmd=cmd, status=status, reason=0, ng=True, data=payload)
|
||||||
@@ -91,7 +91,7 @@ def test_led_brightness():
|
|||||||
|
|
||||||
def test_led_pwm_non_capable_raises():
|
def test_led_pwm_non_capable_raises():
|
||||||
"""PWM on a non-PWM LED should raise PM3Error."""
|
"""PWM on a non-PWM LED should raise PM3Error."""
|
||||||
from pm3py.transport import PM3Error
|
from pm3py.core.transport import PM3Error
|
||||||
import pytest
|
import pytest
|
||||||
transport = make_mock_transport()
|
transport = make_mock_transport()
|
||||||
hw = HWCommands(transport)
|
hw = HWCommands(transport)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import struct
|
|||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import AsyncMock, MagicMock
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
from pm3py import Proxmark3, Cmd
|
from pm3py import Proxmark3, Cmd
|
||||||
from pm3py.client import FirmwareInfo
|
from pm3py.core.client import FirmwareInfo
|
||||||
|
|
||||||
|
|
||||||
def test_full_api_surface():
|
def test_full_api_surface():
|
||||||
@@ -14,9 +14,9 @@ def test_full_api_surface():
|
|||||||
assert hasattr(pm3, "lf")
|
assert hasattr(pm3, "lf")
|
||||||
assert hasattr(pm3, "hf")
|
assert hasattr(pm3, "hf")
|
||||||
assert hasattr(pm3.lf, "t55")
|
assert hasattr(pm3.lf, "t55")
|
||||||
assert hasattr(pm3.hf, "a14")
|
assert hasattr(pm3.hf, "iso14a")
|
||||||
assert hasattr(pm3.hf, "iso15")
|
assert hasattr(pm3.hf, "iso15")
|
||||||
assert hasattr(pm3.hf, "mf")
|
assert hasattr(pm3.hf, "mfc")
|
||||||
assert hasattr(pm3, "send_ng")
|
assert hasattr(pm3, "send_ng")
|
||||||
assert hasattr(pm3, "send_mix")
|
assert hasattr(pm3, "send_mix")
|
||||||
assert hasattr(pm3, "firmware")
|
assert hasattr(pm3, "firmware")
|
||||||
@@ -27,7 +27,7 @@ def test_hw_ping_roundtrip():
|
|||||||
"""Test ping returns structured dict."""
|
"""Test ping returns structured dict."""
|
||||||
pm3 = Proxmark3("/dev/null")
|
pm3 = Proxmark3("/dev/null")
|
||||||
mock_transport = AsyncMock()
|
mock_transport = AsyncMock()
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
ping_data = bytes(range(32))
|
ping_data = bytes(range(32))
|
||||||
mock_transport.send_ng.return_value = PM3Response(
|
mock_transport.send_ng.return_value = PM3Response(
|
||||||
cmd=Cmd.PING, status=0, reason=0, ng=True, data=ping_data)
|
cmd=Cmd.PING, status=0, reason=0, ng=True, data=ping_data)
|
||||||
@@ -41,21 +41,21 @@ def test_mf_rdbl_returns_hex():
|
|||||||
"""Verify MIFARE read returns hex string data."""
|
"""Verify MIFARE read returns hex string data."""
|
||||||
pm3 = Proxmark3("/dev/null")
|
pm3 = Proxmark3("/dev/null")
|
||||||
mock_transport = AsyncMock()
|
mock_transport = AsyncMock()
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
block = bytes(range(16))
|
block = bytes(range(16))
|
||||||
mock_transport.send_ng.return_value = PM3Response(
|
mock_transport.send_ng.return_value = PM3Response(
|
||||||
cmd=Cmd.HF_MIFARE_READBL, status=0, reason=0, ng=True, data=block)
|
cmd=Cmd.HF_MIFARE_READBL, status=0, reason=0, ng=True, data=block)
|
||||||
pm3.hf.mf._t = mock_transport
|
pm3.hf.mfc._t = mock_transport
|
||||||
result = asyncio.get_event_loop().run_until_complete(
|
result = asyncio.get_event_loop().run_until_complete(
|
||||||
pm3.hf.mf.rdbl(block=4, key="FFFFFFFFFFFF"))
|
pm3.hf.mfc.rdbl(block=4, key="FFFFFFFFFFFF"))
|
||||||
assert result["data"] == "000102030405060708090a0b0c0d0e0f"
|
assert result["data"] == "000102030405060708090a0b0c0d0e0f"
|
||||||
assert result["raw"] == block
|
assert result["raw"] == block
|
||||||
|
|
||||||
|
|
||||||
def test_sync_proxy():
|
def test_sync_proxy():
|
||||||
"""Verify sync proxy wraps async calls."""
|
"""Verify sync proxy wraps async calls."""
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
from pm3py.client import _SyncProxy
|
from pm3py.core.client import _SyncProxy
|
||||||
|
|
||||||
pm3 = Proxmark3("/dev/null")
|
pm3 = Proxmark3("/dev/null")
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
@@ -83,7 +83,7 @@ def test_firmware_probe_compatible():
|
|||||||
pm3._transport = mock_transport
|
pm3._transport = mock_transport
|
||||||
pm3.hw._t = mock_transport
|
pm3.hw._t = mock_transport
|
||||||
|
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
|
|
||||||
ping_data = bytes(range(32))
|
ping_data = bytes(range(32))
|
||||||
vstr = b"Proxmark3 RDV4.0 FW v4.18000\x00"
|
vstr = b"Proxmark3 RDV4.0 FW v4.18000\x00"
|
||||||
@@ -109,7 +109,7 @@ def test_firmware_probe_ping_fails():
|
|||||||
pm3._transport = mock_transport
|
pm3._transport = mock_transport
|
||||||
pm3.hw._t = mock_transport
|
pm3.hw._t = mock_transport
|
||||||
|
|
||||||
from pm3py.transport import PM3Response, PM3Error
|
from pm3py.core.transport import PM3Response, PM3Error
|
||||||
|
|
||||||
vstr = b"Proxmark3 OLD\x00"
|
vstr = b"Proxmark3 OLD\x00"
|
||||||
version_payload = struct.pack("<III", 0x270B0A40, 256*1024, len(vstr)) + vstr
|
version_payload = struct.pack("<III", 0x270B0A40, 256*1024, len(vstr)) + vstr
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import struct
|
import struct
|
||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
from pm3py.protocol import Cmd
|
from pm3py.core.protocol import Cmd
|
||||||
from pm3py.transport import PM3Response
|
from pm3py.core.transport import PM3Response
|
||||||
from pm3py.lf import LFCommands
|
from pm3py.core.lf import LFCommands
|
||||||
|
|
||||||
def make_response(cmd, status, data):
|
def make_response(cmd, status, data):
|
||||||
return PM3Response(cmd=cmd, status=status, reason=0, ng=True, data=data)
|
return PM3Response(cmd=cmd, status=status, reason=0, ng=True, data=data)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import struct
|
import struct
|
||||||
from pm3py.transport import encode_ng_frame, decode_response_frame, encode_mix_frame, _crc_to_wire
|
from pm3py.core.transport import encode_ng_frame, decode_response_frame, encode_mix_frame, _crc_to_wire
|
||||||
from pm3py.protocol import Cmd, CMD_PREAMBLE_MAGIC, CMD_POSTAMBLE_NOCRC, RESP_PREAMBLE_MAGIC, RESP_POSTAMBLE_NOCRC, crc16_a
|
from pm3py.core.protocol import Cmd, CMD_PREAMBLE_MAGIC, CMD_POSTAMBLE_NOCRC, RESP_PREAMBLE_MAGIC, RESP_POSTAMBLE_NOCRC, crc16_a
|
||||||
|
|
||||||
def test_encode_ng_frame_ping_no_payload():
|
def test_encode_ng_frame_ping_no_payload():
|
||||||
frame = encode_ng_frame(Cmd.PING, b"")
|
frame = encode_ng_frame(Cmd.PING, b"")
|
||||||
|
|||||||
Reference in New Issue
Block a user