From c1ab98003651ef4164d120617b2363076193ff56 Mon Sep 17 00:00:00 2001 From: michael Date: Wed, 18 Mar 2026 20:56:40 -0700 Subject: [PATCH] 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) --- pm3py/sim/auth_aes.py | 2 - pm3py/sim/auth_password.py | 2 - pm3py/sim/crypto1.py | 2 - pm3py/sim/desfire.py | 2 - pm3py/sim/em4100.py | 2 - pm3py/sim/fuzzer.py | 2 +- pm3py/sim/hid.py | 2 - pm3py/sim/icode3.py | 2 - pm3py/sim/icode_dna.py | 2 - pm3py/sim/icode_slix.py | 2 - pm3py/sim/icode_slix2.py | 2 - pm3py/sim/implants.py | 2 - pm3py/sim/iso14443a.py | 2 - pm3py/sim/iso15693.py | 2 - pm3py/sim/lf_base.py | 2 - pm3py/sim/mifare.py | 2 - pm3py/sim/ndef.py | 2 - pm3py/sim/ntag5_boost.py | 2 - pm3py/sim/ntag5_link.py | 2 - pm3py/sim/ntag5_platform.py | 2 - pm3py/sim/ntag5_switch.py | 2 - pm3py/sim/nxp_icode.py | 2 - pm3py/sim/sim_session.py | 10 +- pm3py/sim/t5577.py | 2 - pm3py/sim/table_compiler.py | 2 +- pm3py/sim/trace_fmt.py | 4 - pm3py/sim/type5.py | 2 - pm3py/transponders/hf/iso14443a/base.py | 2 +- pm3py/transponders/hf/iso15693/base.py | 2 +- .../transponders/hf/iso15693/nxp/nxp_icode.py | 2 +- .../test_crc.cpython-312-pytest-9.0.1.pyc | Bin 4159 -> 4164 bytes tests/test_sim_14443a.py | 2 +- tests/test_sim_15693.py | 2 +- tests/test_sim_advanced.py | 2 +- tests/test_sim_aes_auth.py | 40 ++-- tests/test_sim_desfire.py | 4 +- tests/test_sim_dual_session.py | 2 +- tests/test_sim_icode3.py | 82 ++++---- tests/test_sim_icode_slix.py | 60 +++--- tests/test_sim_implants.py | 12 +- tests/test_sim_lf.py | 8 +- tests/test_sim_memory.py | 14 +- tests/test_sim_mifare.py | 6 +- tests/test_sim_ndef.py | 4 +- tests/test_sim_ntag5.py | 186 +++++++++--------- tests/test_sim_nxp_icode.py | 12 +- tests/test_sim_table_compiler.py | 34 ++-- tests/test_sim_trace_fmt.py | 20 +- 48 files changed, 256 insertions(+), 304 deletions(-) delete mode 100644 pm3py/sim/auth_aes.py delete mode 100644 pm3py/sim/auth_password.py delete mode 100644 pm3py/sim/crypto1.py delete mode 100644 pm3py/sim/desfire.py delete mode 100644 pm3py/sim/em4100.py delete mode 100644 pm3py/sim/hid.py delete mode 100644 pm3py/sim/icode3.py delete mode 100644 pm3py/sim/icode_dna.py delete mode 100644 pm3py/sim/icode_slix.py delete mode 100644 pm3py/sim/icode_slix2.py delete mode 100644 pm3py/sim/implants.py delete mode 100644 pm3py/sim/iso14443a.py delete mode 100644 pm3py/sim/iso15693.py delete mode 100644 pm3py/sim/lf_base.py delete mode 100644 pm3py/sim/mifare.py delete mode 100644 pm3py/sim/ndef.py delete mode 100644 pm3py/sim/ntag5_boost.py delete mode 100644 pm3py/sim/ntag5_link.py delete mode 100644 pm3py/sim/ntag5_platform.py delete mode 100644 pm3py/sim/ntag5_switch.py delete mode 100644 pm3py/sim/nxp_icode.py delete mode 100644 pm3py/sim/t5577.py delete mode 100644 pm3py/sim/trace_fmt.py delete mode 100644 pm3py/sim/type5.py diff --git a/pm3py/sim/auth_aes.py b/pm3py/sim/auth_aes.py deleted file mode 100644 index 40753f7..0000000 --- a/pm3py/sim/auth_aes.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.auth_aes import * # noqa: F401,F403 diff --git a/pm3py/sim/auth_password.py b/pm3py/sim/auth_password.py deleted file mode 100644 index 2fab4a6..0000000 --- a/pm3py/sim/auth_password.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.auth_password import * # noqa: F401,F403 diff --git a/pm3py/sim/crypto1.py b/pm3py/sim/crypto1.py deleted file mode 100644 index b394bb8..0000000 --- a/pm3py/sim/crypto1.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso14443a.nxp.crypto1 import * # noqa: F401,F403 diff --git a/pm3py/sim/desfire.py b/pm3py/sim/desfire.py deleted file mode 100644 index 0d284b7..0000000 --- a/pm3py/sim/desfire.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso14443a.nxp.desfire import * # noqa: F401,F403 diff --git a/pm3py/sim/em4100.py b/pm3py/sim/em4100.py deleted file mode 100644 index 93f85be..0000000 --- a/pm3py/sim/em4100.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.lf.em.em4100 import * # noqa: F401,F403 diff --git a/pm3py/sim/fuzzer.py b/pm3py/sim/fuzzer.py index ffd5025..77442e8 100644 --- a/pm3py/sim/fuzzer.py +++ b/pm3py/sim/fuzzer.py @@ -6,7 +6,7 @@ from typing import Iterator from bitarray import bitarray from .frame import RFFrame -from .iso14443a import CL1, NVB_SELECT, _compute_bcc +from pm3py.transponders.hf.iso14443a.base import CL1, NVB_SELECT, _compute_bcc class MutationFuzzer: diff --git a/pm3py/sim/hid.py b/pm3py/sim/hid.py deleted file mode 100644 index ae7d253..0000000 --- a/pm3py/sim/hid.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.lf.hid.hid import * # noqa: F401,F403 diff --git a/pm3py/sim/icode3.py b/pm3py/sim/icode3.py deleted file mode 100644 index d21c4b4..0000000 --- a/pm3py/sim/icode3.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.icode3 import * # noqa: F401,F403 diff --git a/pm3py/sim/icode_dna.py b/pm3py/sim/icode_dna.py deleted file mode 100644 index a803b71..0000000 --- a/pm3py/sim/icode_dna.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.icode_dna import * # noqa: F401,F403 diff --git a/pm3py/sim/icode_slix.py b/pm3py/sim/icode_slix.py deleted file mode 100644 index 91d34af..0000000 --- a/pm3py/sim/icode_slix.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.icode_slix import * # noqa: F401,F403 diff --git a/pm3py/sim/icode_slix2.py b/pm3py/sim/icode_slix2.py deleted file mode 100644 index abcd7ae..0000000 --- a/pm3py/sim/icode_slix2.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import * # noqa: F401,F403 diff --git a/pm3py/sim/implants.py b/pm3py/sim/implants.py deleted file mode 100644 index 32ac4bd..0000000 --- a/pm3py/sim/implants.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.implants import * # noqa: F401,F403 diff --git a/pm3py/sim/iso14443a.py b/pm3py/sim/iso14443a.py deleted file mode 100644 index 19ba79f..0000000 --- a/pm3py/sim/iso14443a.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso14443a.base import * # noqa: F401,F403 diff --git a/pm3py/sim/iso15693.py b/pm3py/sim/iso15693.py deleted file mode 100644 index 254dfaf..0000000 --- a/pm3py/sim/iso15693.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.base import * # noqa: F401,F403 diff --git a/pm3py/sim/lf_base.py b/pm3py/sim/lf_base.py deleted file mode 100644 index b6de2ff..0000000 --- a/pm3py/sim/lf_base.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.lf.base import * # noqa: F401,F403 diff --git a/pm3py/sim/mifare.py b/pm3py/sim/mifare.py deleted file mode 100644 index a7d06db..0000000 --- a/pm3py/sim/mifare.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso14443a.nxp.mifare_classic import * # noqa: F401,F403 diff --git a/pm3py/sim/ndef.py b/pm3py/sim/ndef.py deleted file mode 100644 index c1d6b09..0000000 --- a/pm3py/sim/ndef.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso14443a.ndef import * # noqa: F401,F403 diff --git a/pm3py/sim/ntag5_boost.py b/pm3py/sim/ntag5_boost.py deleted file mode 100644 index 6fd6ca7..0000000 --- a/pm3py/sim/ntag5_boost.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import * # noqa: F401,F403 diff --git a/pm3py/sim/ntag5_link.py b/pm3py/sim/ntag5_link.py deleted file mode 100644 index 6a42ca9..0000000 --- a/pm3py/sim/ntag5_link.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.ntag5_link import * # noqa: F401,F403 diff --git a/pm3py/sim/ntag5_platform.py b/pm3py/sim/ntag5_platform.py deleted file mode 100644 index 12b5e23..0000000 --- a/pm3py/sim/ntag5_platform.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import * # noqa: F401,F403 diff --git a/pm3py/sim/ntag5_switch.py b/pm3py/sim/ntag5_switch.py deleted file mode 100644 index cf8f3af..0000000 --- a/pm3py/sim/ntag5_switch.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import * # noqa: F401,F403 diff --git a/pm3py/sim/nxp_icode.py b/pm3py/sim/nxp_icode.py deleted file mode 100644 index 1c04a18..0000000 --- a/pm3py/sim/nxp_icode.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.nxp.nxp_icode import * # noqa: F401,F403 diff --git a/pm3py/sim/sim_session.py b/pm3py/sim/sim_session.py index 9ff4c10..1072203 100644 --- a/pm3py/sim/sim_session.py +++ b/pm3py/sim/sim_session.py @@ -10,7 +10,7 @@ import serial from .frame import RFFrame from .table_compiler import ResponseTable, TableCompiler -from .trace_fmt import TraceFormatter +from pm3py.trace.format import TraceFormatter from .transponder import Transponder from ..core.protocol import Cmd from ..core.transport import encode_ng_frame, decode_response_frame, RESP_PREAMBLE_MAGIC, RESP_PREAMBLE_SIZE, RESP_POSTAMBLE_SIZE @@ -184,10 +184,10 @@ class SimSession: table = ResponseTable(entries=[]) # Check most specific IC first, fall back to base - from .icode3 import Icode3Tag - from .icode_dna import IcodeDnaTag - from .icode_slix2 import IcodeSlix2Tag - from .ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag if isinstance(tag, Ntag5PlatformTag): # NTAG 5 Switch/Link/Boost — use DNA compiler (same platform) table = TableCompiler.compile_icode_dna(tag) diff --git a/pm3py/sim/t5577.py b/pm3py/sim/t5577.py deleted file mode 100644 index e183134..0000000 --- a/pm3py/sim/t5577.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.lf.atmel.t5577 import * # noqa: F401,F403 diff --git a/pm3py/sim/table_compiler.py b/pm3py/sim/table_compiler.py index 41f2ef6..9002d5f 100644 --- a/pm3py/sim/table_compiler.py +++ b/pm3py/sim/table_compiler.py @@ -288,7 +288,7 @@ class TableCompiler: first_block = 128 + (sector - 32) * 16 # Pre-pick a tag nonce - from .crypto1 import Crypto1 + from pm3py.transponders.hf.iso14443a.nxp.crypto1 import Crypto1 crypto = Crypto1(key) nt = crypto.generate_nonce() diff --git a/pm3py/sim/trace_fmt.py b/pm3py/sim/trace_fmt.py deleted file mode 100644 index 69d5743..0000000 --- a/pm3py/sim/trace_fmt.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Backward compat shim — moved to pm3py.trace.""" -from pm3py.trace.decode_iso15 import decode_15693, decode_15693_nxp # noqa: F401 -from pm3py.trace.decode_iso14a import decode_14443a # noqa: F401 -from pm3py.trace.format import TraceFormatter # noqa: F401 diff --git a/pm3py/sim/type5.py b/pm3py/sim/type5.py deleted file mode 100644 index df143b0..0000000 --- a/pm3py/sim/type5.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Backward compat shim — moved to pm3py.transponders.""" -from pm3py.transponders.hf.iso15693.type5 import * # noqa: F401,F403 diff --git a/pm3py/transponders/hf/iso14443a/base.py b/pm3py/transponders/hf/iso14443a/base.py index 1e95286..673de79 100644 --- a/pm3py/transponders/hf/iso14443a/base.py +++ b/pm3py/transponders/hf/iso14443a/base.py @@ -5,7 +5,7 @@ from enum import IntEnum from pm3py.sim.frame import RFFrame from pm3py.sim.medium import Medium -from pm3py.sim.trace_fmt import decode_14443a +from pm3py.trace.decode_iso14a import decode_14443a from pm3py.sim.transponder import Transponder from pm3py.sim.reader import Reader diff --git a/pm3py/transponders/hf/iso15693/base.py b/pm3py/transponders/hf/iso15693/base.py index 9d3b5c4..1efef7b 100644 --- a/pm3py/transponders/hf/iso15693/base.py +++ b/pm3py/transponders/hf/iso15693/base.py @@ -7,7 +7,7 @@ from enum import IntEnum from pm3py.sim.frame import RFFrame from pm3py.sim.medium import Medium -from pm3py.sim.trace_fmt import decode_15693 +from pm3py.trace.decode_iso15 import decode_15693 from pm3py.sim.transponder import Transponder from pm3py.sim.reader import Reader diff --git a/pm3py/transponders/hf/iso15693/nxp/nxp_icode.py b/pm3py/transponders/hf/iso15693/nxp/nxp_icode.py index 91aa6c3..0300c4c 100644 --- a/pm3py/transponders/hf/iso15693/nxp/nxp_icode.py +++ b/pm3py/transponders/hf/iso15693/nxp/nxp_icode.py @@ -5,7 +5,7 @@ import os import struct from pm3py.sim.frame import RFFrame -from pm3py.sim.trace_fmt import decode_15693_nxp +from pm3py.trace.decode_iso15 import decode_15693_nxp from ..type5 import NfcType5Tag # NXP manufacturer code diff --git a/tests/__pycache__/test_crc.cpython-312-pytest-9.0.1.pyc b/tests/__pycache__/test_crc.cpython-312-pytest-9.0.1.pyc index fa7703541665b5dd143af873638d70c67046dfd1..62d108d291a77f3fa3103a56b167e2575091fb4f 100644 GIT binary patch delta 60 zcmdn5a72OkG%qg~0}x~-?9QCBk@plow{StOaY3bCa(+?j 3 stays silent.""" - from pm3py.sim.icode_dna import IcodeDnaTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED tag = IcodeDnaTag(aes_keys=[b"\xAA" * 16, None, None, None]) tag._key_headers[0] = KEY_HEADER_ACTIVE_LOCKED @@ -156,8 +156,8 @@ class TestTam1: def test_challenge_wrong_auth_method(self): """CHALLENGE with AuthMethod != 0x00 (not TAM1) stays silent.""" - from pm3py.sim.icode_dna import IcodeDnaTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED tag = IcodeDnaTag(aes_keys=[b"\xAA" * 16, None, None, None]) tag._key_headers[0] = KEY_HEADER_ACTIVE_LOCKED @@ -177,8 +177,8 @@ class TestMam: """Tests for MAM1/MAM2 mutual authentication via AUTHENTICATE (0x35).""" def _make_tag(self, key=b"\xAA" * 16, key_slot=0): - from pm3py.sim.icode_dna import IcodeDnaTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED keys = [None] * 4 keys[key_slot] = key @@ -293,7 +293,7 @@ class TestMam: def test_mam1_inactive_key_error(self): """MAM1 with inactive key returns error.""" - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag(aes_keys=[b"\xAA" * 16, None, None, None]) run(tag.power_on()) @@ -366,7 +366,7 @@ class TestMam: def test_mam2_purpose_enable_privacy(self): """MAM2 with purpose=0x09 sets privacy mode.""" - from pm3py.sim.auth_aes import PRIV_PRIVACY + from pm3py.transponders.hf.iso15693.nxp.auth_aes import PRIV_PRIVACY key = b"\xAA" * 16 tag = self._make_tag(key) @@ -380,7 +380,7 @@ class TestMam: def test_mam2_purpose_disable_privacy(self): """MAM2 with purpose=0x0A clears privacy mode.""" - from pm3py.sim.auth_aes import PRIV_PRIVACY + from pm3py.transponders.hf.iso15693.nxp.auth_aes import PRIV_PRIVACY key = b"\xAA" * 16 tag = self._make_tag(key) @@ -395,7 +395,7 @@ class TestMam: def test_mam2_purpose_destroy(self): """MAM2 with purpose=0x0B sets destroyed.""" - from pm3py.sim.auth_aes import PRIV_DESTROY + from pm3py.transponders.hf.iso15693.nxp.auth_aes import PRIV_DESTROY key = b"\xAA" * 16 tag = self._make_tag(key) diff --git a/tests/test_sim_desfire.py b/tests/test_sim_desfire.py index db26e44..501be49 100644 --- a/tests/test_sim_desfire.py +++ b/tests/test_sim_desfire.py @@ -4,8 +4,8 @@ import pytest from pm3py.sim.frame import RFFrame from pm3py.sim.medium import SoftwareMedium -from pm3py.sim.iso14443a import _compute_bcc -from pm3py.sim.desfire import DesfireTag, DesfireReader +from pm3py.transponders.hf.iso14443a.base import _compute_bcc +from pm3py.transponders.hf.iso14443a.nxp.desfire import DesfireTag, DesfireReader def run(coro): diff --git a/tests/test_sim_dual_session.py b/tests/test_sim_dual_session.py index 64e6ea8..636fda7 100644 --- a/tests/test_sim_dual_session.py +++ b/tests/test_sim_dual_session.py @@ -4,7 +4,7 @@ import pytest from pm3py.sim.dual_session import DualInterfaceSession from pm3py.sim.mcu_bridge import McuBridge from pm3py.sim.mcu_protocol import MsgType, build_frame, cobs_decode, parse_frame -from pm3py.sim.ntag5_link import Ntag5LinkTag +from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag class MockSimSession: diff --git a/tests/test_sim_icode3.py b/tests/test_sim_icode3.py index 676bb56..0cb8d86 100644 --- a/tests/test_sim_icode3.py +++ b/tests/test_sim_icode3.py @@ -4,7 +4,7 @@ import struct import pytest from pm3py.sim.frame import RFFrame -from pm3py.sim.nxp_icode import ( +from pm3py.transponders.hf.iso15693.nxp.nxp_icode import ( CMD_SET_EAS, CMD_READ_CONFIG, CMD_WRITE_CONFIG, CMD_READ_TT, ) @@ -41,20 +41,20 @@ PWD_CONFIG = 0x20 class TestIcode3Basics: def test_import(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag def test_inherits_slix2(self): - from pm3py.sim.icode3 import Icode3Tag - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag assert issubclass(Icode3Tag, IcodeSlix2Tag) def test_default_76_blocks(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) assert tag._num_blocks == 76 def test_responds_to_inventory(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) inv = bytes([0x26, 0x01, 0x00]) @@ -68,14 +68,14 @@ class TestIcode3Basics: class TestIcode3ConfigPassword: def test_config_password_auth(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), config_password=0xDEADBEEF) run(tag.power_on()) _authenticate(tag, PWD_CONFIG, 0xDEADBEEF) def test_config_password_wrong(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), config_password=0xDEADBEEF) run(tag.power_on()) @@ -91,7 +91,7 @@ class TestIcode3ConfigPassword: class TestIcode3InheritsSlix2: def test_eas(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) cmd = bytes([0x02, CMD_SET_EAS, 0x04]) @@ -100,7 +100,7 @@ class TestIcode3InheritsSlix2: assert tag.eas_enabled def test_privacy(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), privacy_password=0xAAAAAAAA) run(tag.power_on()) @@ -108,7 +108,7 @@ class TestIcode3InheritsSlix2: assert tag.privacy_mode def test_destroy(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), destroy_password=0xBBBBBBBB) run(tag.power_on()) @@ -125,7 +125,7 @@ class TestIcode3InheritsSlix2: class TestIcode3Counter: def test_counter_increments_24bit(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -141,7 +141,7 @@ class TestIcode3Counter: assert counter == 1 def test_counter_accumulates(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -155,7 +155,7 @@ class TestIcode3Counter: assert counter == 10 def test_counter_saturates_at_24bit(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -177,7 +177,7 @@ class TestIcode3Counter: assert counter == 0xFFFFFF def test_normal_blocks_still_overwrite(self): - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -198,7 +198,7 @@ class TestIcode3Counter: class TestIcode3Config: def test_read_config(self): """READ CONFIG returns config memory blocks.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -211,7 +211,7 @@ class TestIcode3Config: def test_write_config(self): """WRITE CONFIG writes to config memory.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -228,7 +228,7 @@ class TestIcode3Config: def test_read_config_passwords_masked(self): """READ CONFIG masks password blocks with 0x00.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), read_password=0xDEADBEEF) run(tag.power_on()) @@ -242,7 +242,7 @@ class TestIcode3Config: def test_write_config_requires_auth_when_protected(self): """WRITE CONFIG fails without config password when protected.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), config_password=0xAABBCCDD) run(tag.power_on()) @@ -254,7 +254,7 @@ class TestIcode3Config: def test_read_config_multiple_blocks(self): """READ CONFIG can read multiple blocks.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -273,7 +273,7 @@ class TestIcode3Config: class TestIcode3TagTamper: def test_read_tt_closed(self): """READ TT returns closed status by default.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), tag_tamper=True) run(tag.power_on()) @@ -287,7 +287,7 @@ class TestIcode3TagTamper: def test_read_tt_open(self): """READ TT returns open status when tampered.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), tag_tamper=True) run(tag.power_on()) tag._tt_status_actual = 0x4F # 'O' = Open @@ -298,7 +298,7 @@ class TestIcode3TagTamper: def test_read_tt_not_supported_without_flag(self): """READ TT returns error when tag_tamper=False.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), tag_tamper=False) run(tag.power_on()) @@ -314,7 +314,7 @@ class TestIcode3TagTamper: class TestIcode3SystemInfo: def test_feature_flags(self): """GET NXP SYSTEM INFO returns ICODE 3 feature flags.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -338,7 +338,7 @@ class TestIcode3SystemInfo: class TestIcode3NfcMirror: def test_uid_mirror(self): """UID mirror overlays 16 ASCII hex bytes into user memory on read.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06") run(tag.power_on()) @@ -354,7 +354,7 @@ class TestIcode3NfcMirror: def test_uid_counter_mirror(self): """UID + counter mirror: 16 bytes UID + 'x' + 6 bytes counter.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06") run(tag.power_on()) @@ -380,7 +380,7 @@ class TestIcode3NfcMirror: def test_mirror_disabled(self): """With mirror disabled (sel=0), reads return physical memory.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06") run(tag.power_on()) @@ -397,7 +397,7 @@ class TestIcode3NfcMirror: def test_mirror_with_byte_offset(self): """Mirror starting at byte 2 within a block.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06") run(tag.power_on()) @@ -417,7 +417,7 @@ class TestIcode3NfcMirror: def test_mirror_outside_block_returns_physical(self): """Blocks before mirror region return physical memory.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06") run(tag.power_on()) @@ -438,7 +438,7 @@ class TestIcode3NfcMirror: class TestIcode3PrivacyMode2: def test_privacy_mode2_inventory_zeroed_uid(self): """In privacy mode 2, inventory returns zeroed UID.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06", privacy_password=0xDEADBEEF) run(tag.power_on()) @@ -455,7 +455,7 @@ class TestIcode3PrivacyMode2: def test_privacy_mode2_allows_reads(self): """Privacy mode 2 allows READ SINGLE BLOCK.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06", privacy_password=0xDEADBEEF) run(tag.power_on()) @@ -475,7 +475,7 @@ class TestIcode3PrivacyMode2: def test_privacy_mode1_blocks_reads(self): """Privacy mode 1 blocks everything except GET_RANDOM/SET_PASSWORD.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06", privacy_password=0xDEADBEEF) run(tag.power_on()) @@ -489,7 +489,7 @@ class TestIcode3PrivacyMode2: def test_pick_random_id(self): """PICK RANDOM ID (0xC2) generates random UID for inventory.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06", privacy_password=0xDEADBEEF) run(tag.power_on()) @@ -514,7 +514,7 @@ class TestIcode3PrivacyMode2: def test_pick_random_id_fails_outside_privacy(self): """PICK RANDOM ID fails when not in privacy mode.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20\x03\x04\x05\x06") run(tag.power_on()) @@ -530,7 +530,7 @@ class TestIcode3PrivacyMode2: class TestIcode3Signature48: def test_default_32_byte_signature(self): """Default READ SIGNATURE returns 32 bytes (1 flag + 32 sig = 33).""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -542,7 +542,7 @@ class TestIcode3Signature48: def test_48_byte_signature_mode(self): """With 48-byte mode enabled, READ SIGNATURE returns 49 bytes.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag sig48 = bytes(range(48)) tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), signature=sig48) run(tag.power_on()) @@ -557,7 +557,7 @@ class TestIcode3Signature48: def test_48_byte_mode_disabled_truncates(self): """With 48-byte mode disabled, READ SIGNATURE returns first 32 bytes.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag sig48 = bytes(range(48)) tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4), signature=sig48) run(tag.power_on()) @@ -574,7 +574,7 @@ class TestIcode3Signature48: class TestIcode3CounterPreset: def test_value_0x000001_increments(self): """Writing 0x000001 to block 75 increments counter by 1.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -590,7 +590,7 @@ class TestIcode3CounterPreset: def test_value_not_0x000001_presets(self): """Writing != 0x000001 to block 75 presets (overwrites) counter.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -610,7 +610,7 @@ class TestIcode3CounterPreset: def test_0x000001_twice_increments_twice(self): """Writing 0x000001 twice increments counter from 0 → 1 → 2.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) @@ -625,7 +625,7 @@ class TestIcode3CounterPreset: def test_prot_byte_written(self): """PROT byte (data[3]) is written to memory alongside counter.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(uid=b"\xE0\x04\x01\x20" + bytes(4)) run(tag.power_on()) diff --git a/tests/test_sim_icode_slix.py b/tests/test_sim_icode_slix.py index dc019c6..11120f1 100644 --- a/tests/test_sim_icode_slix.py +++ b/tests/test_sim_icode_slix.py @@ -4,7 +4,7 @@ import struct import pytest from pm3py.sim.frame import RFFrame -from pm3py.sim.nxp_icode import ( +from pm3py.transponders.hf.iso15693.nxp.nxp_icode import ( CMD_SET_EAS, CMD_RESET_EAS, CMD_LOCK_EAS, CMD_EAS_ALARM, CMD_PASSWORD_PROTECT_EAS_AFI, CMD_WRITE_EAS_ID, CMD_INVENTORY_READ, CMD_FAST_INVENTORY_READ, @@ -45,23 +45,23 @@ PWD_EAS_AFI = 0x10 class TestIcodeSlixBasics: def test_import(self): """IcodeSlixTag can be imported.""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag def test_inherits_nxp_icode(self): """SLIX inherits from NxpIcodeTag.""" - from pm3py.sim.icode_slix import IcodeSlixTag - from pm3py.sim.nxp_icode import NxpIcodeTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.nxp_icode import NxpIcodeTag assert issubclass(IcodeSlixTag, NxpIcodeTag) def test_default_28_blocks(self): """SLIX defaults to 28 blocks × 4 bytes.""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) assert tag._num_blocks == 28 assert tag._block_size == 4 def test_responds_to_inventory(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) inv = bytes([0x26, 0x01, 0x00]) @@ -69,7 +69,7 @@ class TestIcodeSlixBasics: assert resp is not None def test_read_write_block(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) # Write block 5 @@ -89,7 +89,7 @@ class TestIcodeSlixBasics: class TestIcodeSlixPassword: def test_set_password_eas_afi(self): """SET_PASSWORD with correct EAS/AFI password succeeds.""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4), eas_afi_password=0xAABBCCDD) run(tag.power_on()) @@ -97,7 +97,7 @@ class TestIcodeSlixPassword: def test_set_password_wrong(self): """SET_PASSWORD with wrong password fails.""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4), eas_afi_password=0xAABBCCDD) run(tag.power_on()) @@ -108,7 +108,7 @@ class TestIcodeSlixPassword: def test_write_password(self): """WRITE_PASSWORD changes the EAS/AFI password.""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4), eas_afi_password=0xAABBCCDD) run(tag.power_on()) @@ -122,7 +122,7 @@ class TestIcodeSlixPassword: def test_lock_password(self): """LOCK_PASSWORD prevents WRITE_PASSWORD.""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4), eas_afi_password=0xAABBCCDD) run(tag.power_on()) @@ -139,7 +139,7 @@ class TestIcodeSlixPassword: def test_no_privacy_password(self): """SLIX has no privacy — only EAS/AFI password accepted.""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4), eas_afi_password=0xAABBCCDD) run(tag.power_on()) @@ -156,7 +156,7 @@ class TestIcodeSlixPassword: class TestIcodeSlixEas: def test_set_eas(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) cmd = bytes([0x02, CMD_SET_EAS, 0x04]) @@ -165,7 +165,7 @@ class TestIcodeSlixEas: assert tag.eas_enabled def test_reset_eas(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) tag.set_eas(True) @@ -175,7 +175,7 @@ class TestIcodeSlixEas: assert not tag.eas_enabled def test_eas_alarm(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) tag.set_eas(True) @@ -186,7 +186,7 @@ class TestIcodeSlixEas: assert len(resp.data) >= 33 def test_eas_alarm_silent_when_disabled(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) cmd = bytes([0x02, CMD_EAS_ALARM, 0x04]) @@ -194,7 +194,7 @@ class TestIcodeSlixEas: assert resp is None def test_lock_eas(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) tag.set_eas(True) @@ -207,7 +207,7 @@ class TestIcodeSlixEas: assert resp.data[0] & 0x01 def test_password_protect_eas_afi(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4), eas_afi_password=0xAABBCCDD) run(tag.power_on()) @@ -219,7 +219,7 @@ class TestIcodeSlixEas: def test_write_eas_id(self): """WRITE EAS ID is SLIX2-only (EAS Selective per AN11809).""" - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5), eas_afi_password=0xAABBCCDD) run(tag.power_on()) @@ -231,7 +231,7 @@ class TestIcodeSlixEas: def test_slix_rejects_write_eas_id(self): """SLIX (SL2S2002) does not support WRITE EAS ID (0xA7).""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) cmd = bytes([0x02, CMD_WRITE_EAS_ID, 0x04, 0x34, 0x12]) @@ -245,7 +245,7 @@ class TestIcodeSlixEas: class TestIcodeSlixInventoryRead: def test_inventory_read(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10\x03\x04\x05\x06") run(tag.power_on()) cmd = bytes([0x06, CMD_INVENTORY_READ, 0x04, 0x00, 0x00, 0x00]) @@ -254,7 +254,7 @@ class TestIcodeSlixInventoryRead: assert resp.data[0] == 0x00 def test_fast_inventory_read(self): - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10\x03\x04\x05\x06") run(tag.power_on()) cmd = bytes([0x06, CMD_FAST_INVENTORY_READ, 0x04, 0x00, 0x00, 0x00]) @@ -271,12 +271,12 @@ class TestSlix2StillWorks: """Verify SLIX2 inherits from SLIX and retains all features.""" def test_slix2_inherits_slix(self): - from pm3py.sim.icode_slix import IcodeSlixTag - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag assert issubclass(IcodeSlix2Tag, IcodeSlixTag) def test_slix2_privacy_still_works(self): - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5), privacy_password=0xDEADBEEF) run(tag.power_on()) @@ -284,7 +284,7 @@ class TestSlix2StillWorks: assert tag.privacy_mode def test_slix2_destroy_still_works(self): - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5), destroy_password=0xDEAD1234) run(tag.power_on()) @@ -298,7 +298,7 @@ class TestSlix2StillWorks: def test_slix2_eas_inherited_from_slix(self): """SLIX2 EAS works via inheritance from SLIX.""" - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5)) run(tag.power_on()) cmd = bytes([0x02, CMD_SET_EAS, 0x04]) @@ -314,7 +314,7 @@ class TestSlix2StillWorks: class TestSlixLacksPrivacy: def test_no_enable_privacy(self): """SLIX does not respond to ENABLE PRIVACY (0xBA).""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) cmd = bytes([0x02, 0xBA, 0x04, 0x00, 0x00, 0x00, 0x00]) @@ -324,7 +324,7 @@ class TestSlixLacksPrivacy: def test_no_destroy(self): """SLIX does not respond to DESTROY (0xB9).""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) cmd = bytes([0x02, 0xB9, 0x04, 0x00, 0x00, 0x00, 0x00]) @@ -333,7 +333,7 @@ class TestSlixLacksPrivacy: def test_no_protect_page(self): """SLIX does not respond to PROTECT PAGE (0xB6).""" - from pm3py.sim.icode_slix import IcodeSlixTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag tag = IcodeSlixTag(uid=b"\xE0\x04\x01\x10" + bytes(4)) run(tag.power_on()) cmd = bytes([0x02, 0xB6, 0x04, 0x08, 0x01]) diff --git a/tests/test_sim_implants.py b/tests/test_sim_implants.py index ebb7366..57c1eb2 100644 --- a/tests/test_sim_implants.py +++ b/tests/test_sim_implants.py @@ -3,12 +3,12 @@ import asyncio import pytest from pm3py.sim.medium import SoftwareMedium -from pm3py.sim.implants import ( +from pm3py.transponders.implants import ( xEM, xNT, xM1, FlexDF, NExT, MagicMifareClassicTag, ) -from pm3py.sim.em4100 import EM4100Reader -from pm3py.sim.iso14443a import Reader14443A, _compute_bcc +from pm3py.transponders.lf.em.em4100 import EM4100Reader +from pm3py.transponders.hf.iso14443a.base import Reader14443A, _compute_bcc def run(coro): @@ -36,7 +36,7 @@ class TestXNT: assert tag._total_pages >= 45 # NTAG213+ size def test_is_type2_tag(self): - from pm3py.sim.ndef import NfcType2Tag + from pm3py.transponders.hf.iso14443a.ndef import NfcType2Tag tag = xNT() assert isinstance(tag, NfcType2Tag) @@ -77,7 +77,7 @@ class TestMagicMifareClassic: class TestFlexDF: def test_creates_desfire(self): - from pm3py.sim.desfire import DesfireTag + from pm3py.transponders.hf.iso14443a.nxp.desfire import DesfireTag tag = FlexDF() assert isinstance(tag, DesfireTag) @@ -92,7 +92,7 @@ class TestNExT: # LF side is T5577 configured as EM4100 assert lf.blocks[0] != 0 # HF side is NfcType2Tag (xNT) - from pm3py.sim.ndef import NfcType2Tag + from pm3py.transponders.hf.iso14443a.ndef import NfcType2Tag assert isinstance(hf, NfcType2Tag) def test_both_sides_work(self): diff --git a/tests/test_sim_lf.py b/tests/test_sim_lf.py index 5d92665..b6026a5 100644 --- a/tests/test_sim_lf.py +++ b/tests/test_sim_lf.py @@ -4,10 +4,10 @@ import pytest from pm3py.sim.frame import RFFrame from pm3py.sim.medium import SoftwareMedium -from pm3py.sim.lf_base import TagLF, ReaderLF, Modulation -from pm3py.sim.em4100 import EM4100Tag, EM4100Reader -from pm3py.sim.hid import HIDProxTag, HIDReader -from pm3py.sim.t5577 import T5577Tag, T5577Reader +from pm3py.transponders.lf.base import TagLF, ReaderLF, Modulation +from pm3py.transponders.lf.em.em4100 import EM4100Tag, EM4100Reader +from pm3py.transponders.lf.hid.hid import HIDProxTag, HIDReader +from pm3py.transponders.lf.atmel.t5577 import T5577Tag, T5577Reader def run(coro): diff --git a/tests/test_sim_memory.py b/tests/test_sim_memory.py index c8630c2..184cd50 100644 --- a/tests/test_sim_memory.py +++ b/tests/test_sim_memory.py @@ -140,14 +140,14 @@ class TestTransponderRegions: class TestTag15693Regions: def test_has_user_region(self): - from pm3py.sim.iso15693 import Tag15693 + from pm3py.transponders.hf.iso15693.base import Tag15693 tag = Tag15693(uid=bytes(8), block_size=4, num_blocks=28) assert "user" in tag.regions assert tag.regions["user"].block_size == 4 assert tag.regions["user"].eml_offset == 175 def test_memory_property_aliases_region(self): - from pm3py.sim.iso15693 import Tag15693 + from pm3py.transponders.hf.iso15693.base import Tag15693 tag = Tag15693(uid=bytes(8), block_size=4, num_blocks=28) tag._memory[0:4] = b"\xDE\xAD\xBE\xEF" assert tag.regions["user"].data[0:4] == b"\xDE\xAD\xBE\xEF" @@ -156,7 +156,7 @@ class TestTag15693Regions: class TestIcodeSlix2AccessMap: def test_protection_pointer_sets_access_map(self): - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5), protection_pointer=4, read_password=0xAABBCCDD) user = tag.regions["user"] @@ -166,7 +166,7 @@ class TestIcodeSlix2AccessMap: assert user.access_for_block(4).read_key == 1 def test_no_protection_pointer_all_open(self): - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5)) user = tag.regions["user"] assert user.access_for_block(0).read == "open" @@ -177,7 +177,7 @@ class TestIcodeSlix2AccessMap: class TestCompileFromRegions: def test_open_blocks_have_data_entries(self): - from pm3py.sim.iso15693 import Tag15693 + from pm3py.transponders.hf.iso15693.base import Tag15693 from pm3py.sim.table_compiler import TableCompiler tag = Tag15693(uid=bytes(8), block_size=4, num_blocks=4) tag._memory[0:4] = b"\xDE\xAD\xBE\xEF" @@ -187,7 +187,7 @@ class TestCompileFromRegions: assert entry.response[1:5] == b"\xDE\xAD\xBE\xEF" def test_protected_blocks_without_auth(self): - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag from pm3py.sim.table_compiler import TableCompiler tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5), protection_pointer=2, read_password=0xAABBCCDD, block_size=4, num_blocks=4) @@ -198,7 +198,7 @@ class TestCompileFromRegions: assert table.lookup(bytes([0x02, 0x20, 0x02])) is None def test_protected_blocks_with_auth(self): - from pm3py.sim.icode_slix2 import IcodeSlix2Tag, PWD_READ + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag, PWD_READ from pm3py.sim.table_compiler import TableCompiler tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5), protection_pointer=2, read_password=0xAABBCCDD, block_size=4, num_blocks=4) diff --git a/tests/test_sim_mifare.py b/tests/test_sim_mifare.py index 015ee62..453c18c 100644 --- a/tests/test_sim_mifare.py +++ b/tests/test_sim_mifare.py @@ -5,9 +5,9 @@ import pytest from pm3py.sim.frame import RFFrame from pm3py.sim.medium import SoftwareMedium -from pm3py.sim.crypto1 import Crypto1 -from pm3py.sim.mifare import MifareClassicTag, MifareClassicReader -from pm3py.sim.iso14443a import Reader14443A, REQA, CL1, NVB_SELECT, _compute_bcc +from pm3py.transponders.hf.iso14443a.nxp.crypto1 import Crypto1 +from pm3py.transponders.hf.iso14443a.nxp.mifare_classic import MifareClassicTag, MifareClassicReader +from pm3py.transponders.hf.iso14443a.base import Reader14443A, REQA, CL1, NVB_SELECT, _compute_bcc def run(coro): diff --git a/tests/test_sim_ndef.py b/tests/test_sim_ndef.py index da1b599..210b1a2 100644 --- a/tests/test_sim_ndef.py +++ b/tests/test_sim_ndef.py @@ -4,8 +4,8 @@ import pytest from pm3py.sim.frame import RFFrame from pm3py.sim.medium import SoftwareMedium -from pm3py.sim.iso14443a import Reader14443A, _compute_bcc -from pm3py.sim.ndef import NfcType2Tag, NfcType4Tag +from pm3py.transponders.hf.iso14443a.base import Reader14443A, _compute_bcc +from pm3py.transponders.hf.iso14443a.ndef import NfcType2Tag, NfcType4Tag def run(coro): diff --git a/tests/test_sim_ntag5.py b/tests/test_sim_ntag5.py index adfa708..688c1b0 100644 --- a/tests/test_sim_ntag5.py +++ b/tests/test_sim_ntag5.py @@ -15,45 +15,45 @@ def run(coro): class TestIcodeDna: def test_inherits_slix2(self): - from pm3py.sim.icode_dna import IcodeDnaTag - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag assert issubclass(IcodeDnaTag, IcodeSlix2Tag) def test_default_64_blocks(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() assert tag._num_blocks == 64 def test_uid_prefix(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() assert tag._uid[:4] == b"\xE0\x04\x01\x18" def test_counter_on_last_block(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() user = tag.regions["user"] assert user.access_for_block(63).write_mode == "counter" def test_4_aes_keys(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() assert len(tag._aes_keys) == 4 assert all(k is None for k in tag._aes_keys) def test_aes_keys_from_constructor(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag key0 = b"\xAA" * 16 tag = IcodeDnaTag(aes_keys=[key0, None, None, None]) assert tag._aes_keys[0] == key0 def test_config_memory_48_blocks(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() assert len(tag._config_memory) == 48 * 4 def test_read_config(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() run(tag.power_on()) # Read config header block 0x08 @@ -64,7 +64,7 @@ class TestIcodeDna: assert resp.data[1] == 0x81 # CONFIG_HEADER_WRITABLE default def test_write_config(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() run(tag.power_on()) # Write CID to block 0x09 @@ -78,7 +78,7 @@ class TestIcodeDna: def test_key_storage_masked_when_active(self): """Key blocks return zeros when key header is active.""" - from pm3py.sim.icode_dna import IcodeDnaTag, KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag, KEY_HEADER_ACTIVE_LOCKED tag = IcodeDnaTag(aes_keys=[b"\xAA" * 16, None, None, None]) run(tag.power_on()) @@ -95,7 +95,7 @@ class TestIcodeDna: def test_key_write_rejected_when_active(self): """Cannot write key blocks when header is active.""" - from pm3py.sim.icode_dna import IcodeDnaTag, KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag, KEY_HEADER_ACTIVE_LOCKED tag = IcodeDnaTag() run(tag.power_on()) tag._key_headers[0] = KEY_HEADER_ACTIVE_LOCKED @@ -106,7 +106,7 @@ class TestIcodeDna: def test_key_header_one_way(self): """Key header only goes up (lower → higher values).""" - from pm3py.sim.icode_dna import IcodeDnaTag, KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag, KEY_HEADER_ACTIVE_LOCKED tag = IcodeDnaTag() run(tag.power_on()) @@ -118,7 +118,7 @@ class TestIcodeDna: def test_gch_one_way(self): """NFC_GCH only programs one-way.""" - from pm3py.sim.icode_dna import IcodeDnaTag, GCH_ACTIVATED + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag, GCH_ACTIVATED tag = IcodeDnaTag() run(tag.power_on()) @@ -129,19 +129,19 @@ class TestIcodeDna: assert tag._nfc_gch == GCH_ACTIVATED def test_cid_default(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() assert tag._cid == 0xC000 def test_responds_to_inventory(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() run(tag.power_on()) resp = run(tag.handle_frame(RFFrame.from_bytes(bytes([0x26, 0x01, 0x00])))) assert resp is not None def test_inherits_eas(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() run(tag.power_on()) cmd = bytes([0x02, 0xA2, 0x04]) @@ -156,12 +156,12 @@ class TestIcodeDna: class TestNtag5Platform: def test_config_memory(self): - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag tag = Ntag5PlatformTag(num_blocks=128) assert len(tag._config_memory) >= 160 * 4 def test_read_config(self): - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag tag = Ntag5PlatformTag(num_blocks=128) run(tag.power_on()) cmd = bytes([0x02, 0xC0, 0x04, 0x3F, 0x00]) @@ -171,7 +171,7 @@ class TestNtag5Platform: assert resp.data[1] == 0xA5 # DEV_SEC_CONFIG default def test_write_config(self): - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag tag = Ntag5PlatformTag(num_blocks=128) run(tag.power_on()) cmd = bytes([0x02, 0xC1, 0x04, 0x57, 0x34, 0x12, 0x00, 0x00]) @@ -189,36 +189,36 @@ class TestNtag5Platform: class TestNtag5Switch: def test_inherits_platform(self): - from pm3py.sim.ntag5_switch import Ntag5SwitchTag - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag assert issubclass(Ntag5SwitchTag, Ntag5PlatformTag) def test_default_128_blocks(self): - from pm3py.sim.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag tag = Ntag5SwitchTag() assert tag._num_blocks == 128 def test_no_aes(self): - from pm3py.sim.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag tag = Ntag5SwitchTag() assert not tag._aes_capable def test_counter_on_block_127(self): - from pm3py.sim.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag tag = Ntag5SwitchTag() user = tag.regions["user"] assert user.access_for_block(127).write_mode == "counter" assert user.access_for_block(0).write_mode == "normal" def test_responds_to_inventory(self): - from pm3py.sim.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag tag = Ntag5SwitchTag() run(tag.power_on()) resp = run(tag.handle_frame(RFFrame.from_bytes(bytes([0x26, 0x01, 0x00])))) assert resp is not None def test_switch_rejects_stay_quiet_persistent(self): - from pm3py.sim.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag tag = Ntag5SwitchTag() run(tag.power_on()) cmd = bytes([0x22, 0xBC]) + tag._uid[::-1] + bytes([0x04]) @@ -233,33 +233,33 @@ class TestNtag5Switch: class TestNtag5Link: def test_inherits_platform(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag assert issubclass(Ntag5LinkTag, Ntag5PlatformTag) def test_default_512_blocks(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() assert tag._num_blocks == 512 def test_i2c_address(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() assert tag.i2c_address == 0x54 def test_sram(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() assert len(tag.sram) == 256 def test_i2c_sram_roundtrip(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() tag.i2c_write(0x2000, b"\xAA\xBB\xCC\xDD") assert tag.i2c_read(0x2000, 4) == b"\xAA\xBB\xCC\xDD" def test_sram_mirror_read(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR tag = Ntag5LinkTag() run(tag.power_on()) tag._sram_enabled = True @@ -270,12 +270,12 @@ class TestNtag5Link: assert resp.data[1:5] == b"\xDE\xAD\xBE\xEF" def test_password_only_variant(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag(aes_capable=False) assert not tag._aes_capable def test_aes_variant(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag(aes_capable=True) assert tag._aes_capable @@ -286,33 +286,33 @@ class TestNtag5Link: class TestArbitration: def test_acquire_nfc_succeeds_no_lock(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() assert tag.acquire_nfc() is True assert tag.nfc_if_locked is True def test_acquire_nfc_fails_when_i2c_locked(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() tag.set_i2c_locked(True) assert tag.acquire_nfc() is False assert tag.nfc_if_locked is False def test_acquire_i2c_succeeds_no_lock(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() assert tag.acquire_i2c() is True assert tag.i2c_if_locked is True def test_acquire_i2c_fails_when_nfc_locked(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() tag.set_nfc_locked(True) assert tag.acquire_i2c() is False assert tag.i2c_if_locked is False def test_release_clears_lock(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() tag.acquire_nfc() assert tag.nfc_if_locked is True @@ -325,7 +325,7 @@ class TestArbitration: assert tag.i2c_if_locked is False def test_nfc_sram_read_blocked_when_i2c_locked(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR tag = Ntag5LinkTag() run(tag.power_on()) tag._sram_enabled = True @@ -339,7 +339,7 @@ class TestArbitration: assert resp.data[1] == 0x0F def test_nfc_sram_read_works_with_nfc_lock(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR tag = Ntag5LinkTag() run(tag.power_on()) tag._sram_enabled = True @@ -352,21 +352,21 @@ class TestArbitration: assert resp.data[1:5] == b"\xDE\xAD\xBE\xEF" def test_i2c_sram_read_blocked_when_nfc_locked(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() tag.set_nfc_locked(True) result = tag.i2c_read(0x2000, 4) assert result is None def test_i2c_sram_write_blocked_when_nfc_locked(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() tag.set_nfc_locked(True) result = tag.i2c_write(0x2000, b"\x01\x02\x03\x04") assert result is False def test_lock_unlock_sequential_access(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() # NFC acquires, writes via SRAM directly, releases @@ -391,27 +391,27 @@ class TestArbitration: class TestNtag5Boost: def test_inherits_link(self): - from pm3py.sim.ntag5_boost import Ntag5BoostTag - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag assert issubclass(Ntag5BoostTag, Ntag5LinkTag) def test_aes_always(self): - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() assert tag._aes_capable def test_default_512_blocks(self): - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() assert tag._num_blocks == 512 def test_has_sram(self): - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() assert len(tag.sram) == 256 def test_boost_rejects_stay_quiet_persistent(self): - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() run(tag.power_on()) cmd = bytes([0x22, 0xBC]) + tag._uid[::-1] + bytes([0x04]) @@ -428,7 +428,7 @@ class TestSessionRegisters: """Session register state machine for NTAG 5 platform.""" def _make_tag(self): - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag tag = Ntag5PlatformTag(num_blocks=128) run(tag.power_on()) return tag @@ -553,8 +553,8 @@ class TestNtag5Aes: def test_link_5332_tam1(self): """TAM1 (CHALLENGE + READBUFFER) works on Link NTP5332 (aes_capable=True).""" - from pm3py.sim.ntag5_link import Ntag5LinkTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED from Crypto.Cipher import AES key = b"\xCC" * 16 @@ -586,8 +586,8 @@ class TestNtag5Aes: def test_link_5332_tam1_readbuffer_one_shot(self): """READBUFFER is one-shot — second read returns None.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED key = b"\xCC" * 16 tag = Ntag5LinkTag(aes_capable=True) @@ -607,7 +607,7 @@ class TestNtag5Aes: def test_switch_no_aes_challenge_rejected(self): """CHALLENGE on Switch (no AES) does not produce a valid response.""" - from pm3py.sim.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag tag = Ntag5SwitchTag() run(tag.power_on()) @@ -620,7 +620,7 @@ class TestNtag5Aes: def test_link_no_aes_challenge_rejected(self): """CHALLENGE on Link NTP5312 (aes_capable=False) does not work.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag(aes_capable=False) run(tag.power_on()) @@ -631,8 +631,8 @@ class TestNtag5Aes: def test_boost_mam1(self): """MAM1 (AUTHENTICATE with AuthMethod=0x02) works on Boost.""" - from pm3py.sim.ntag5_boost import Ntag5BoostTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED from Crypto.Cipher import AES key = b"\xDD" * 16 @@ -663,8 +663,8 @@ class TestNtag5Aes: def test_boost_mam2(self): """Full MAM1 + MAM2 mutual authentication on Boost.""" - from pm3py.sim.ntag5_boost import Ntag5BoostTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED from Crypto.Cipher import AES key = b"\xEE" * 16 @@ -708,8 +708,8 @@ class TestNtag5Aes: def test_boost_mam2_wrong_key_fails(self): """MAM2 with wrong key is rejected.""" - from pm3py.sim.ntag5_boost import Ntag5BoostTag - from pm3py.sim.auth_aes import KEY_HEADER_ACTIVE_LOCKED + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.auth_aes import KEY_HEADER_ACTIVE_LOCKED from Crypto.Cipher import AES key = b"\xEE" * 16 @@ -735,7 +735,7 @@ class TestNtag5Aes: def test_link_no_aes_authenticate_rejected(self): """AUTHENTICATE on Link NTP5312 (no AES) returns error.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag(aes_capable=False) run(tag.power_on()) @@ -748,7 +748,7 @@ class TestNtag5Aes: def test_boost_inherits_slix2_commands(self): """AES-capable Boost still handles SLIX2 commands (e.g. inventory, read).""" - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() run(tag.power_on()) @@ -772,13 +772,13 @@ class TestConfigReg: """CONFIG_REG (session register block 0xA1) bit-field accessors and enforcement.""" def _make_platform_tag(self): - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag tag = Ntag5PlatformTag(num_blocks=128) run(tag.power_on()) return tag def _make_link_tag(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) return tag @@ -869,7 +869,7 @@ class TestPassThrough: """SRAM pass-through mode (arbiter_mode == 2).""" def _make_tag(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag, ARBITER_PASSTHROUGH + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag, ARBITER_PASSTHROUGH tag = Ntag5LinkTag() run(tag.power_on()) tag.sram_enable = True @@ -946,7 +946,7 @@ class TestPassThrough: def test_passthrough_not_active_in_normal_mode(self): """Pass-through behavior inactive when arbiter_mode is NORMAL.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag, ARBITER_NORMAL + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag, ARBITER_NORMAL tag = Ntag5LinkTag() run(tag.power_on()) tag.sram_enable = True @@ -958,7 +958,7 @@ class TestPassThrough: def test_passthrough_not_active_in_mirror_mode(self): """Pass-through behavior inactive when arbiter_mode is MIRROR.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag, ARBITER_MIRROR tag = Ntag5LinkTag() run(tag.power_on()) tag.sram_enable = True @@ -998,7 +998,7 @@ class TestSynchDataBlock: """Synch data block triggers status register flags on access.""" def _make_tag(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) return tag @@ -1075,7 +1075,7 @@ class TestEventDetection: """ED pin callbacks and trigger logic for NTAG 5 platform.""" def _make_tag(self): - from pm3py.sim.ntag5_platform import Ntag5PlatformTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import Ntag5PlatformTag tag = Ntag5PlatformTag(num_blocks=128) run(tag.power_on()) return tag @@ -1178,7 +1178,7 @@ class TestReadSram: """Direct SRAM read via NXP custom command 0xD2.""" def _make_tag(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) tag.sram_enable = True @@ -1216,7 +1216,7 @@ class TestReadSram: def test_error_when_sram_disabled(self): """Error (0x01, 0x0F) when SRAM is not enabled.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) # sram_enable defaults to False @@ -1248,7 +1248,7 @@ class TestWriteSram: """Direct SRAM write via NXP custom command 0xD3.""" def _make_tag(self): - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) tag.sram_enable = True @@ -1275,7 +1275,7 @@ class TestWriteSram: def test_error_when_sram_disabled(self): """Error (0x01, 0x0F) when SRAM is not enabled.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) cmd = bytes([0x02, 0xD3, 0x04, 0x00, 0x01, 0xDE, 0xAD, 0xBE, 0xEF]) @@ -1302,7 +1302,7 @@ class TestDualInterfaceIntegration: def _make_tag(self, pt_dir_nfc_to_i2c: bool = True): """Create an Ntag5LinkTag configured for pass-through mode.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) tag.sram_enable = True @@ -1411,7 +1411,7 @@ class TestDualInterfaceIntegration: def test_session_register_consistency(self): """STATUS_REG reflects complete state after a cycle.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) tag.sram_enable = True @@ -1473,7 +1473,7 @@ class TestDualInterfaceIntegration: def test_ed_pin_fires_on_synch_data_block_access(self): """ED pin fires when NFC writes to the configured synch data block.""" - from pm3py.sim.ntag5_link import Ntag5LinkTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_link import Ntag5LinkTag tag = Ntag5LinkTag() run(tag.power_on()) @@ -1516,8 +1516,8 @@ class TestNtag5Area1Passwords: """AREA_1 password IDs (0x40/0x80) per NTP5210/NTA5332 datasheets.""" def test_area1_password_ids_exist_on_switch(self): - from pm3py.sim.ntag5_switch import Ntag5SwitchTag - from pm3py.sim.ntag5_platform import PWD_AREA1_READ, PWD_AREA1_WRITE + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import PWD_AREA1_READ, PWD_AREA1_WRITE tag = Ntag5SwitchTag() assert PWD_AREA1_READ == 0x40 assert PWD_AREA1_WRITE == 0x80 @@ -1532,7 +1532,7 @@ class TestNtag5PickRandomUid: """PICK RANDOM UID (0xC2) per NTA5332 datasheet 8.2.4.9.15.""" def test_pick_random_uid_in_privacy_mode(self): - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() run(tag.power_on()) tag._privacy_mode = True @@ -1546,7 +1546,7 @@ class TestNtag5PickRandomUid: assert tag._random_uid[:2] == b"\xE0\x04" def test_pick_random_uid_without_privacy_mode_returns_error(self): - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() run(tag.power_on()) assert tag._privacy_mode is False @@ -1559,7 +1559,7 @@ class TestNtag5PickRandomUid: def test_switch_rejects_pick_random_uid(self): """NTP5210 does not support PICK RANDOM UID per datasheet rev 3.2.""" - from pm3py.sim.ntag5_switch import Ntag5SwitchTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import Ntag5SwitchTag tag = Ntag5SwitchTag() run(tag.power_on()) # Test outside privacy mode — should get error via custom command dispatch @@ -1580,7 +1580,7 @@ class TestExtendedCommands: def test_extended_read_single_block(self): """Read block 256 (beyond 1-byte range) using extended read single.""" import struct - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() run(tag.power_on()) # Write known data to block 256 @@ -1597,7 +1597,7 @@ class TestExtendedCommands: def test_extended_read_single_block_addressed(self): """Extended read single in addressed mode.""" import struct - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() run(tag.power_on()) offset = 300 * tag._block_size @@ -1612,7 +1612,7 @@ class TestExtendedCommands: def test_extended_write_single_block(self): """Write to block 300 using extended write, then read back.""" import struct - from pm3py.sim.ntag5_boost import Ntag5BoostTag + from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import Ntag5BoostTag tag = Ntag5BoostTag() run(tag.power_on()) block_le = struct.pack(" 0 def test_compile_icode3_includes_slix2_entries(self): """ICODE 3 table includes SLIX2 base entries.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag() table = TableCompiler.compile_icode3(tag) # Should have GET_RANDOM, GET_NXP_SYSTEM_INFO, READ_SIGNATURE @@ -432,7 +432,7 @@ class TestTableCompilerIcode3: def test_compile_icode3_system_info_has_feature_flags(self): """ICODE 3 GET NXP SYSTEM INFO has proper feature flags.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag() table = TableCompiler.compile_icode3(tag) entry = table.lookup(bytes([0x02, 0xAB])) @@ -444,7 +444,7 @@ class TestTableCompilerIcode3: def test_compile_icode3_config_password(self): """ICODE 3 table includes config password (pwd_id 0x20).""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag tag = Icode3Tag(config_password=0xAABBCCDD) table = TableCompiler.compile_icode3(tag) auth_entries = [e for e in table.entries if e.set_auth != 0] @@ -457,7 +457,7 @@ class TestTableCompilerIcode3: def test_session_dispatches_icode3(self): """SimSession uses compile_icode3 for Icode3Tag.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag from pm3py.sim.sim_session import SimSession from unittest.mock import MagicMock @@ -478,14 +478,14 @@ class TestTableCompilerIcode3: class TestTableCompilerDna: def test_compile_icode_dna_exists(self): - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() table = TableCompiler.compile_icode_dna(tag) assert len(table.entries) > 0 def test_compile_includes_base_entries(self): """DNA table includes GET_RANDOM, READ_SIGNATURE from NXP base.""" - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() table = TableCompiler.compile_icode_dna(tag) assert table.lookup(bytes([0x02, 0xB2])) is not None # GET_RANDOM @@ -493,7 +493,7 @@ class TestTableCompilerDna: def test_compile_has_dna_feature_flags(self): """GET NXP SYSTEM INFO has DNA-specific feature flags.""" - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() table = TableCompiler.compile_icode_dna(tag) entry = table.lookup(bytes([0x02, 0xAB])) @@ -507,7 +507,7 @@ class TestTableCompilerDna: def test_compile_has_eas(self): """DNA table includes EAS entries.""" - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag tag = IcodeDnaTag() tag.set_eas(True) table = TableCompiler.compile_icode_dna(tag) @@ -516,7 +516,7 @@ class TestTableCompilerDna: def test_session_dispatches_dna(self): """SimSession uses compile_icode_dna for IcodeDnaTag.""" - from pm3py.sim.icode_dna import IcodeDnaTag + from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag from pm3py.sim.sim_session import SimSession from unittest.mock import MagicMock @@ -538,7 +538,7 @@ class TestTableCompilerDna: class TestSimSessionTableCompile: def test_start_15693_compiles_nxp_table(self): """SimSession uses compile_icode3 for Icode3Tag.""" - from pm3py.sim.icode3 import Icode3Tag + from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag from pm3py.sim.sim_session import SimSession from unittest.mock import MagicMock diff --git a/tests/test_sim_trace_fmt.py b/tests/test_sim_trace_fmt.py index bb0ef39..23b5954 100644 --- a/tests/test_sim_trace_fmt.py +++ b/tests/test_sim_trace_fmt.py @@ -2,7 +2,9 @@ import os import pytest -from pm3py.sim.trace_fmt import decode_15693, decode_15693_nxp, decode_14443a, TraceFormatter +from pm3py.trace.decode_iso15 import decode_15693, decode_15693_nxp +from pm3py.trace.decode_iso14a import decode_14443a +from pm3py.trace.format import TraceFormatter class TestDecode15693Request: @@ -391,7 +393,7 @@ class TestTraceFormatterWrapping: def test_long_annotation_wraps_to_next_line(self): cc = bytes([0xE1, 0x40, 0x0D, 0x01]) - from pm3py.sim.type5 import ndef_text + from pm3py.transponders.hf.iso15693.type5 import ndef_text msg = ndef_text("A" * 30) tlv = bytes([0x03, len(msg)]) + msg + bytes([0xFE]) payload = bytes([0x00]) + cc + tlv @@ -490,44 +492,44 @@ class TestTransponderDecodeTrace: assert hasattr(Transponder, 'decode_trace') def test_tag15693_decodes_standard(self): - from pm3py.sim.iso15693 import Tag15693 + from pm3py.transponders.hf.iso15693.base import Tag15693 tag = Tag15693(uid=bytes(8)) result = tag.decode_trace(0, bytes([0x26, 0x01, 0x00])) assert result == "INVENTORY" def test_tag15693_decodes_nxp_names(self): """Base Tag15693 decodes NXP command names (via standard decoder).""" - from pm3py.sim.iso15693 import Tag15693 + from pm3py.transponders.hf.iso15693.base import Tag15693 tag = Tag15693(uid=bytes(8)) result = tag.decode_trace(0, bytes([0x22, 0xA1, 0x04, 0x02])) assert result == "NXP FAST INVENTORY READ" def test_nxp_icode_decodes_nxp(self): - from pm3py.sim.nxp_icode import NxpIcodeTag + from pm3py.transponders.hf.iso15693.nxp.nxp_icode import NxpIcodeTag tag = NxpIcodeTag(uid=b"\xE0\x04" + bytes(6)) result = tag.decode_trace(0, bytes([0x22, 0xA1, 0x04, 0x02])) assert result == "NXP FAST INVENTORY READ" def test_nxp_icode_falls_back_to_standard(self): - from pm3py.sim.nxp_icode import NxpIcodeTag + from pm3py.transponders.hf.iso15693.nxp.nxp_icode import NxpIcodeTag tag = NxpIcodeTag(uid=b"\xE0\x04" + bytes(6)) result = tag.decode_trace(0, bytes([0x26, 0x01, 0x00])) assert result == "INVENTORY" def test_icode_slix2_inherits_nxp(self): - from pm3py.sim.icode_slix2 import IcodeSlix2Tag + from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag tag = IcodeSlix2Tag(uid=b"\xE0\x04\x02" + bytes(5)) result = tag.decode_trace(0, bytes([0x22, 0xB2, 0x04])) assert result == "NXP GET RANDOM" def test_tag14443a_decodes(self): - from pm3py.sim.iso14443a import Tag14443A + from pm3py.transponders.hf.iso14443a.base import Tag14443A tag = Tag14443A(uid=bytes(4)) result = tag.decode_trace(0, bytes([0x26])) assert result == "REQA" def test_tag14443a_no_15693(self): - from pm3py.sim.iso14443a import Tag14443A + from pm3py.transponders.hf.iso14443a.base import Tag14443A tag = Tag14443A(uid=bytes(4)) result = tag.decode_trace(0, bytes([0x26, 0x01, 0x00])) # 14443a decoder sees 0x26 as REQA (single byte check happens first)