refactor: remove all backward-compat shims from sim/
Deletes 24 shim files from sim/. All test imports now point directly to canonical transponders/ and trace/ paths. sim/ contains only infrastructure (15 files): frame, memory, transponder ABC, reader ABC, medium, sim_session, table_compiler, replay, relay, fuzzer, pm3medium, mcu_bridge, mcu_protocol, dual_session, __init__. 751 tests passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.auth_aes import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.auth_password import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso14443a.nxp.crypto1 import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso14443a.nxp.desfire import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.lf.em.em4100 import * # noqa: F401,F403
|
||||
@@ -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:
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.lf.hid.hid import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode3 import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_dna import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_slix import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.implants import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso14443a.base import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.base import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.lf.base import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso14443a.nxp.mifare_classic import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso14443a.ndef import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.ntag5_boost import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.ntag5_link import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.ntag5_switch import * # noqa: F401,F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.nxp.nxp_icode import * # noqa: F401,F403
|
||||
@@ -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)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.lf.atmel.t5577 import * # noqa: F401,F403
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
"""Backward compat shim — moved to pm3py.transponders."""
|
||||
from pm3py.transponders.hf.iso15693.type5 import * # noqa: F401,F403
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -5,7 +5,7 @@ from bitarray import bitarray
|
||||
|
||||
from pm3py.sim.frame import RFFrame
|
||||
from pm3py.sim.medium import SoftwareMedium
|
||||
from pm3py.sim.iso14443a import (
|
||||
from pm3py.transponders.hf.iso14443a.base import (
|
||||
Tag14443A, Tag14443A_3, Tag14443A_4, Reader14443A,
|
||||
State14443A, REQA, WUPA, HLTA, CL1, CL2, CL3,
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import pytest
|
||||
|
||||
from pm3py.sim.frame import RFFrame
|
||||
from pm3py.sim.medium import SoftwareMedium
|
||||
from pm3py.sim.iso15693 import Tag15693, Reader15693, State15693
|
||||
from pm3py.transponders.hf.iso15693.base import Tag15693, Reader15693, State15693
|
||||
|
||||
|
||||
def run(coro):
|
||||
|
||||
@@ -4,7 +4,7 @@ import pytest
|
||||
|
||||
from pm3py.sim.frame import RFFrame
|
||||
from pm3py.sim.medium import SoftwareMedium
|
||||
from pm3py.sim.iso14443a import Tag14443A_3, Reader14443A
|
||||
from pm3py.transponders.hf.iso14443a.base import Tag14443A_3, Reader14443A
|
||||
from pm3py.sim.fuzzer import MutationFuzzer, GrammarFuzzer
|
||||
from pm3py.sim.relay import RelayTransponder, MitMProxy
|
||||
from pm3py.sim.replay import TraceRecorder, TraceReplayer, TraceEntry
|
||||
|
||||
@@ -15,8 +15,8 @@ def run(coro):
|
||||
class TestTam1:
|
||||
def test_challenge_readbuffer(self):
|
||||
"""Full TAM1 flow: CHALLENGE computes TResponse, READBUFFER returns it."""
|
||||
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
|
||||
|
||||
key = b"\xAA" * 16
|
||||
tag = IcodeDnaTag(aes_keys=[key, None, None, None])
|
||||
@@ -50,8 +50,8 @@ class TestTam1:
|
||||
|
||||
def test_challenge_key1(self):
|
||||
"""TAM1 with key slot 1."""
|
||||
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
|
||||
|
||||
key = b"\xCC" * 16
|
||||
tag = IcodeDnaTag(aes_keys=[None, key, None, None])
|
||||
@@ -75,7 +75,7 @@ class TestTam1:
|
||||
|
||||
def test_challenge_inactive_key_silent(self):
|
||||
"""CHALLENGE with inactive key: tag stays silent, READBUFFER returns nothing."""
|
||||
from pm3py.sim.icode_dna import IcodeDnaTag
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag
|
||||
|
||||
tag = IcodeDnaTag(aes_keys=[b"\xBB" * 16, None, None, None])
|
||||
# Key header NOT active (default 0x81)
|
||||
@@ -92,7 +92,7 @@ class TestTam1:
|
||||
|
||||
def test_readbuffer_without_challenge(self):
|
||||
"""READBUFFER without prior CHALLENGE returns nothing."""
|
||||
from pm3py.sim.icode_dna import IcodeDnaTag
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag
|
||||
|
||||
tag = IcodeDnaTag()
|
||||
run(tag.power_on())
|
||||
@@ -103,8 +103,8 @@ class TestTam1:
|
||||
|
||||
def test_readbuffer_one_shot(self):
|
||||
"""TResponse is cleared after first READBUFFER (one-shot)."""
|
||||
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
|
||||
|
||||
key = b"\xDD" * 16
|
||||
tag = IcodeDnaTag(aes_keys=[key, None, None, None])
|
||||
@@ -126,8 +126,8 @@ class TestTam1:
|
||||
|
||||
def test_challenge_no_key_in_slot(self):
|
||||
"""CHALLENGE with None key slot 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=[None, None, None, None])
|
||||
tag._key_headers[0] = KEY_HEADER_ACTIVE_LOCKED
|
||||
@@ -143,8 +143,8 @@ class TestTam1:
|
||||
|
||||
def test_challenge_invalid_key_id(self):
|
||||
"""CHALLENGE with key_id > 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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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("<H", 300)
|
||||
@@ -1629,7 +1629,7 @@ class TestExtendedCommands:
|
||||
def test_extended_read_multiple_blocks(self):
|
||||
"""Read 3 blocks starting at block 256."""
|
||||
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())
|
||||
bs = tag._block_size
|
||||
@@ -1649,7 +1649,7 @@ class TestExtendedCommands:
|
||||
def test_extended_read_last_block_boost(self):
|
||||
"""Block 511 (last block of Boost) is readable via extended read."""
|
||||
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())
|
||||
last = tag._num_blocks - 1 # 511
|
||||
@@ -1664,7 +1664,7 @@ class TestExtendedCommands:
|
||||
def test_extended_read_out_of_range(self):
|
||||
"""Block 512 on Boost (512 blocks) returns error."""
|
||||
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("<H", 512)
|
||||
@@ -1677,7 +1677,7 @@ class TestExtendedCommands:
|
||||
def test_extended_read_multiple_overflow(self):
|
||||
"""Extended read multiple that would go past end returns error."""
|
||||
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("<H", 510)
|
||||
|
||||
@@ -5,18 +5,18 @@ import pytest
|
||||
|
||||
from pm3py.sim.frame import RFFrame
|
||||
from pm3py.sim.medium import SoftwareMedium
|
||||
from pm3py.sim.type5 import NfcType5Tag
|
||||
from pm3py.sim.nxp_icode import NxpIcodeTag
|
||||
from pm3py.sim.icode_slix import IcodeSlixTag
|
||||
from pm3py.sim.icode_slix2 import (
|
||||
from pm3py.transponders.hf.iso15693.type5 import NfcType5Tag
|
||||
from pm3py.transponders.hf.iso15693.nxp.nxp_icode import NxpIcodeTag
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_slix import IcodeSlixTag
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import (
|
||||
IcodeSlix2Tag, PWD_EAS_AFI, PWD_READ, PWD_WRITE, PWD_PRIVACY, PWD_DESTROY,
|
||||
)
|
||||
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,
|
||||
)
|
||||
from pm3py.sim.iso15693 import Reader15693
|
||||
from pm3py.transponders.hf.iso15693.base import Reader15693
|
||||
|
||||
|
||||
def run(coro):
|
||||
|
||||
@@ -5,16 +5,16 @@ import pytest
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from pm3py.sim.frame import RFFrame
|
||||
from pm3py.sim.iso14443a import Tag14443A_3, Tag14443A_4, _compute_bcc
|
||||
from pm3py.sim.mifare import MifareClassicTag
|
||||
from pm3py.sim.iso15693 import Tag15693
|
||||
from pm3py.sim.desfire import DesfireTag
|
||||
from pm3py.transponders.hf.iso14443a.base import Tag14443A_3, Tag14443A_4, _compute_bcc
|
||||
from pm3py.transponders.hf.iso14443a.nxp.mifare_classic import MifareClassicTag
|
||||
from pm3py.transponders.hf.iso15693.base import Tag15693
|
||||
from pm3py.transponders.hf.iso14443a.nxp.desfire import DesfireTag
|
||||
from pm3py.sim.table_compiler import (
|
||||
TableEntry, ResponseTable, TableCompiler,
|
||||
EML_READ, EML_WRITE, MATCH_PREFIX,
|
||||
)
|
||||
from pm3py.sim.nxp_icode import NxpIcodeTag
|
||||
from pm3py.sim.icode_slix2 import IcodeSlix2Tag
|
||||
from pm3py.transponders.hf.iso15693.nxp.nxp_icode import NxpIcodeTag
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag
|
||||
|
||||
|
||||
def run(coro):
|
||||
@@ -415,14 +415,14 @@ class TestTableCompilerEasAlarm:
|
||||
|
||||
class TestTableCompilerIcode3:
|
||||
def test_compile_icode3_exists(self):
|
||||
from pm3py.sim.icode3 import Icode3Tag
|
||||
from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag
|
||||
tag = Icode3Tag()
|
||||
table = TableCompiler.compile_icode3(tag)
|
||||
assert len(table.entries) > 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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user