feat(registers): ICODE feature-flags decoder (GET NXP SYSTEM INFO)
Add IcodeFeatureFlags (Register) for the 16-bit ICODE feature word reported by GET NXP SYSTEM INFO (ICODE 3 Table 113; DNA/SLIX2 report a subset). Read-only capability decoder — decode a captured word to see what a tag supports. Fields mirror the existing _FEATURE_* constants one-to-one (asserted in a test). 3 new tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ from pm3py.transponders.hf.iso15693.type5 import NfcType5Tag, ndef_text, ndef_ur
|
|||||||
from pm3py.transponders.hf.iso15693.nxp.nxp_icode import NxpIcodeTag
|
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_slix import IcodeSlixTag
|
||||||
from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag
|
from pm3py.transponders.hf.iso15693.nxp.icode_slix2 import IcodeSlix2Tag
|
||||||
from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag
|
from pm3py.transponders.hf.iso15693.nxp.icode3 import Icode3Tag, IcodeFeatureFlags
|
||||||
from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag
|
from pm3py.transponders.hf.iso15693.nxp.icode_dna import IcodeDnaTag
|
||||||
from pm3py.transponders.hf.iso15693.nxp.auth_aes import NxpKeyPrivileges
|
from pm3py.transponders.hf.iso15693.nxp.auth_aes import NxpKeyPrivileges
|
||||||
from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import (
|
from pm3py.transponders.hf.iso15693.nxp.ntag5_platform import (
|
||||||
@@ -115,7 +115,7 @@ __all__ = [
|
|||||||
"Icode3Tag", "IcodeDnaTag",
|
"Icode3Tag", "IcodeDnaTag",
|
||||||
"Ntag5PlatformTag", "Ntag5SwitchTag", "Ntag5LinkTag", "Ntag5BoostTag",
|
"Ntag5PlatformTag", "Ntag5SwitchTag", "Ntag5LinkTag", "Ntag5BoostTag",
|
||||||
"Ntag5StatusReg", "Ntag5ConfigReg",
|
"Ntag5StatusReg", "Ntag5ConfigReg",
|
||||||
"NxpKeyPrivileges",
|
"NxpKeyPrivileges", "IcodeFeatureFlags",
|
||||||
"DesfireTag", "DesfireReader",
|
"DesfireTag", "DesfireReader",
|
||||||
"xEM", "xNT", "xM1", "FlexDF", "NExT", "MagicMifareClassicTag",
|
"xEM", "xNT", "xM1", "FlexDF", "NExT", "MagicMifareClassicTag",
|
||||||
"MutationFuzzer", "GrammarFuzzer",
|
"MutationFuzzer", "GrammarFuzzer",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import os
|
|||||||
import struct
|
import struct
|
||||||
|
|
||||||
from pm3py.sim.frame import RFFrame
|
from pm3py.sim.frame import RFFrame
|
||||||
|
from pm3py.transponders.bitfield import BitField, Register
|
||||||
from .icode_slix2 import IcodeSlix2Tag, PWD_READ, PWD_WRITE
|
from .icode_slix2 import IcodeSlix2Tag, PWD_READ, PWD_WRITE
|
||||||
from .nxp_icode import NXP_MFG
|
from .nxp_icode import NXP_MFG
|
||||||
|
|
||||||
@@ -44,6 +45,33 @@ _FEATURE_WRITE_CID = 1 << 14
|
|||||||
_FEATURE_HIGH_DATA_RATES = 1 << 15
|
_FEATURE_HIGH_DATA_RATES = 1 << 15
|
||||||
|
|
||||||
|
|
||||||
|
class IcodeFeatureFlags(Register):
|
||||||
|
"""The NXP ICODE feature-flags word reported by GET NXP SYSTEM INFO (ICODE 3 Table 113;
|
||||||
|
ICODE DNA / SLIX2 report a subset). Read-only capability bits — decode a word you captured
|
||||||
|
to see what a tag supports. 16-bit little-endian on the wire, but treated here as one word
|
||||||
|
(bit N is feature flag N)."""
|
||||||
|
|
||||||
|
_width_bits = 16
|
||||||
|
_label = "ICODE feature flags"
|
||||||
|
|
||||||
|
um_pp = BitField(0, doc="user-memory password protection")
|
||||||
|
counter = BitField(1, doc="single-block read counter")
|
||||||
|
eas_id = BitField(2, doc="EAS ID")
|
||||||
|
eas_pp = BitField(3, doc="EAS password protection")
|
||||||
|
afi_pp = BitField(4, doc="AFI password protection")
|
||||||
|
inventory_read_ext = BitField(5, doc="extended INVENTORY READ")
|
||||||
|
eas_ir = BitField(6, doc="EAS in INVENTORY READ")
|
||||||
|
cid = BitField(7, doc="configurable customer ID")
|
||||||
|
originality_sig = BitField(8, doc="ECC originality signature")
|
||||||
|
tagtamper = BitField(9, doc="tag-tamper feature")
|
||||||
|
p_quiet = BitField(10, doc="persistent QUIET state")
|
||||||
|
nfc_mirror = BitField(11, doc="NFC ASCII mirror")
|
||||||
|
privacy = BitField(12, doc="privacy mode")
|
||||||
|
destroy = BitField(13, doc="DESTROY command")
|
||||||
|
write_cid = BitField(14, doc="writeable customer ID")
|
||||||
|
high_data_rates = BitField(15, doc="high data-rate support")
|
||||||
|
|
||||||
|
|
||||||
class Icode3Tag(IcodeSlix2Tag):
|
class Icode3Tag(IcodeSlix2Tag):
|
||||||
"""ICODE 3 transponder (SL2S3003 / SL2S3003TT).
|
"""ICODE 3 transponder (SL2S3003 / SL2S3003TT).
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from pm3py.sim import (
|
|||||||
NtagI2CConfig, NtagI2CSession, NtagI2CPtI2C, NT3H2111, NT3H2211,
|
NtagI2CConfig, NtagI2CSession, NtagI2CPtI2C, NT3H2111, NT3H2211,
|
||||||
Ntag5StatusReg, Ntag5ConfigReg, Ntag5LinkTag,
|
Ntag5StatusReg, Ntag5ConfigReg, Ntag5LinkTag,
|
||||||
NxpKeyPrivileges, IcodeDnaTag,
|
NxpKeyPrivileges, IcodeDnaTag,
|
||||||
|
IcodeFeatureFlags,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -467,3 +468,26 @@ class TestNxpKeyPrivileges:
|
|||||||
text = repr(NxpKeyPrivileges.build(read=True, destroy=True))
|
text = repr(NxpKeyPrivileges.build(read=True, destroy=True))
|
||||||
assert "NXP key privileges" in text
|
assert "NXP key privileges" in text
|
||||||
assert "read" in text and "destroy" in text
|
assert "read" in text and "destroy" in text
|
||||||
|
|
||||||
|
|
||||||
|
class TestIcodeFeatureFlags:
|
||||||
|
def test_bits_match_module_constants(self):
|
||||||
|
import pm3py.transponders.hf.iso15693.nxp.icode3 as ic3
|
||||||
|
# every declared field must line up with the _FEATURE_* constant of the same name
|
||||||
|
for name, bf in IcodeFeatureFlags.fields():
|
||||||
|
const = getattr(ic3, f"_FEATURE_{name.upper()}")
|
||||||
|
assert (1 << bf.lo) == const, name
|
||||||
|
|
||||||
|
def test_decode(self):
|
||||||
|
# um_pp(0) + counter(1) + originality_sig(8) + high_data_rates(15)
|
||||||
|
w = (1 << 0) | (1 << 1) | (1 << 8) | (1 << 15)
|
||||||
|
f = IcodeFeatureFlags(w)
|
||||||
|
assert f.um_pp is True and f.counter is True
|
||||||
|
assert f.originality_sig is True and f.high_data_rates is True
|
||||||
|
assert f.privacy is False
|
||||||
|
assert int(f) == w
|
||||||
|
|
||||||
|
def test_repr(self):
|
||||||
|
text = repr(IcodeFeatureFlags(0x0001))
|
||||||
|
assert "ICODE feature flags" in text
|
||||||
|
assert "um_pp" in text
|
||||||
|
|||||||
Reference in New Issue
Block a user