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:
michael
2026-03-18 19:34:48 -07:00
41 changed files with 150 additions and 47 deletions

View File

@@ -1,4 +1,4 @@
from pm3py.protocol import crc16_a
from pm3py.core.protocol import crc16_a
def test_crc16_a_empty():
assert crc16_a(b"") == 0x6363 # init 0xC6C6 reflected = 0x6363

View File

@@ -1,8 +1,8 @@
import asyncio
from unittest.mock import AsyncMock
from pm3py.protocol import Cmd
from pm3py.transport import PM3Response
from pm3py.hf import HFCommands
from pm3py.core.protocol import Cmd
from pm3py.core.transport import PM3Response
from pm3py.core.hf import HFCommands
def test_hf_tune():
t = AsyncMock()

View File

@@ -1,9 +1,9 @@
import struct
import asyncio
from unittest.mock import AsyncMock
from pm3py.protocol import Cmd
from pm3py.transport import PM3Response
from pm3py.hf_14a import HF14ACommands
from pm3py.core.protocol import Cmd
from pm3py.core.transport import PM3Response
from pm3py.core.hf_iso14a import HF14ACommands
def test_14a_scan():
t = AsyncMock()

View File

@@ -1,15 +1,14 @@
import asyncio
import struct
from unittest.mock import AsyncMock
from pm3py.protocol import Cmd
from pm3py.transport import PM3Response
from pm3py.hf_15 import (
from pm3py.core.protocol import Cmd
from pm3py.core.transport import PM3Response
from pm3py.core.hf_iso15 import (
HF15Commands, parse_tracelog, TRACELOG_HDR_SIZE,
decode_15693_request, decode_15693_response, decode_15693,
format_sniff_line, decode_ndef_annotation,
)
def test_15_scan():
t = AsyncMock()
iso15 = HF15Commands(t)

View File

@@ -1,9 +1,9 @@
import struct
import asyncio
from unittest.mock import AsyncMock
from pm3py.protocol import Cmd
from pm3py.transport import PM3Response
from pm3py.hf_mf import HFMFCommands
from pm3py.core.protocol import Cmd
from pm3py.core.transport import PM3Response
from pm3py.core.hf_mfc import HFMFCommands
def test_mf_rdbl():
t = AsyncMock()

View File

@@ -1,9 +1,9 @@
import struct
import asyncio
from unittest.mock import AsyncMock
from pm3py.protocol import Cmd
from pm3py.transport import PM3Response
from pm3py.hw import HWCommands
from pm3py.core.protocol import Cmd
from pm3py.core.transport import PM3Response
from pm3py.core.hw import HWCommands
def make_ng_response(cmd: int, status: int, payload: bytes) -> PM3Response:
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():
"""PWM on a non-PWM LED should raise PM3Error."""
from pm3py.transport import PM3Error
from pm3py.core.transport import PM3Error
import pytest
transport = make_mock_transport()
hw = HWCommands(transport)

View File

@@ -3,7 +3,7 @@ import struct
import asyncio
from unittest.mock import AsyncMock, MagicMock
from pm3py import Proxmark3, Cmd
from pm3py.client import FirmwareInfo
from pm3py.core.client import FirmwareInfo
def test_full_api_surface():
@@ -14,9 +14,9 @@ def test_full_api_surface():
assert hasattr(pm3, "lf")
assert hasattr(pm3, "hf")
assert hasattr(pm3.lf, "t55")
assert hasattr(pm3.hf, "a14")
assert hasattr(pm3.hf, "iso14a")
assert hasattr(pm3.hf, "iso15")
assert hasattr(pm3.hf, "mf")
assert hasattr(pm3.hf, "mfc")
assert hasattr(pm3, "send_ng")
assert hasattr(pm3, "send_mix")
assert hasattr(pm3, "firmware")
@@ -27,7 +27,7 @@ def test_hw_ping_roundtrip():
"""Test ping returns structured dict."""
pm3 = Proxmark3("/dev/null")
mock_transport = AsyncMock()
from pm3py.transport import PM3Response
from pm3py.core.transport import PM3Response
ping_data = bytes(range(32))
mock_transport.send_ng.return_value = PM3Response(
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."""
pm3 = Proxmark3("/dev/null")
mock_transport = AsyncMock()
from pm3py.transport import PM3Response
from pm3py.core.transport import PM3Response
block = bytes(range(16))
mock_transport.send_ng.return_value = PM3Response(
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(
pm3.hf.mf.rdbl(block=4, key="FFFFFFFFFFFF"))
pm3.hf.mfc.rdbl(block=4, key="FFFFFFFFFFFF"))
assert result["data"] == "000102030405060708090a0b0c0d0e0f"
assert result["raw"] == block
def test_sync_proxy():
"""Verify sync proxy wraps async calls."""
from pm3py.transport import PM3Response
from pm3py.client import _SyncProxy
from pm3py.core.transport import PM3Response
from pm3py.core.client import _SyncProxy
pm3 = Proxmark3("/dev/null")
loop = asyncio.new_event_loop()
@@ -83,7 +83,7 @@ def test_firmware_probe_compatible():
pm3._transport = mock_transport
pm3.hw._t = mock_transport
from pm3py.transport import PM3Response
from pm3py.core.transport import PM3Response
ping_data = bytes(range(32))
vstr = b"Proxmark3 RDV4.0 FW v4.18000\x00"
@@ -109,7 +109,7 @@ def test_firmware_probe_ping_fails():
pm3._transport = 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"
version_payload = struct.pack("<III", 0x270B0A40, 256*1024, len(vstr)) + vstr

View File

@@ -1,9 +1,9 @@
import struct
import asyncio
from unittest.mock import AsyncMock
from pm3py.protocol import Cmd
from pm3py.transport import PM3Response
from pm3py.lf import LFCommands
from pm3py.core.protocol import Cmd
from pm3py.core.transport import PM3Response
from pm3py.core.lf import LFCommands
def make_response(cmd, status, data):
return PM3Response(cmd=cmd, status=status, reason=0, ng=True, data=data)

View File

@@ -1,6 +1,6 @@
import struct
from pm3py.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.transport import encode_ng_frame, decode_response_frame, encode_mix_frame, _crc_to_wire
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():
frame = encode_ng_frame(Cmd.PING, b"")