feat(registers): ST25DV RF_Ai_SS area-security register

Add St25dvRfAreaSS (Register) for the ST25DV per-area RF security
registers (RFA1SS..RFA4SS): pwd_ctrl (which RF password gates the area)
and rw_protection (read/write protection level). Bound via
tag.rf_area_ss(area) / tag.set_rf_area_ss(area, value). Modelled from
the model's own tested protection logic (single source of truth) and
cross-checked against _read_allowed / _write_allowed. 3 new tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
michael
2026-07-14 09:05:55 -07:00
parent f9e56e32ef
commit 130bcd1a90
3 changed files with 67 additions and 3 deletions

View File

@@ -11,6 +11,7 @@ from pm3py.sim import (
Ntag5StatusReg, Ntag5ConfigReg, Ntag5LinkTag,
NxpKeyPrivileges, IcodeDnaTag,
IcodeFeatureFlags,
St25dvRfAreaSS, ST25DV04K,
)
@@ -491,3 +492,30 @@ class TestIcodeFeatureFlags:
text = repr(IcodeFeatureFlags(0x0001))
assert "ICODE feature flags" in text
assert "um_pp" in text
class TestSt25dvRfAreaSS:
def test_fields(self):
r = St25dvRfAreaSS(0)
r.rw_protection = 2 # bits 3:2
r.pwd_ctrl = 1 # bits 1:0
assert int(r) == (2 << 2) | 1 # 0x09
assert r.rw_protection == "read+write need password"
assert r.pwd_ctrl == "RF_PWD_1"
def test_binding_matches_protection_logic(self):
tag = ST25DV04K()
r = St25dvRfAreaSS(0)
r.rw_protection = 3 # write locked
tag.set_rf_area_ss(1, r)
assert tag.rf_area_ss(1).rw_protection == "read needs password / write locked"
# the tag's existing protection logic must see the very same bits
assert tag._write_allowed(4) is False # level 3 -> write forbidden
assert tag._read_allowed(4) is False # level 3, no session -> read denied
def test_open_area(self):
tag = ST25DV04K()
tag.set_rf_area_ss(1, St25dvRfAreaSS(0)) # level 0 = fully open
assert tag.rf_area_ss(1).rw_protection == "open (read+write)"
assert tag._write_allowed(4) is True
assert tag._read_allowed(4) is True