feat(sim): reject wrong-protocol tags in start_14a/start_15693; export tags; uid getter

- start_14a now raises TypeError for a non-Tag14443A transponder, start_15693
  likewise for a non-Tag15693 (local imports to avoid the base<->sim circular
  import). Prevents silently starting a sim with an incompatible tag model.
- Re-export the full 14a/14b/15693 tag lineup (NTAG21x, Ultralight family, NTAG
  I2C, ST25*, OPTIGA, ISO14443B, TI parts) from pm3py.sim for `from pm3py.sim
  import NTAG213`-style use.
- Add a read-only `uid` property on the Transponder base (mirrors set_uid()).
- Tests for both guards.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
michael
2026-07-05 12:58:37 -07:00
parent 77ff1bb076
commit a24f0f803f
4 changed files with 91 additions and 0 deletions

View File

@@ -115,3 +115,25 @@ def test_14a_entries_accumulate_and_clear():
assert [e["direction"] for e in s.entries] == [0, 1]
s.clear()
assert s.entries == []
def test_start_14a_rejects_non_14443a_tag():
"""A 15693 (or any non-Tag14443A) transponder must be refused up front."""
import pytest
from pm3py.sim import Icode3Tag
s = SimSession()
s._port = MagicMock() # would otherwise fail on port resolution
with pytest.raises(TypeError, match="ISO 14443-A"):
s.start_14a(Icode3Tag(uid=None))
def test_start_15693_rejects_non_15693_tag():
"""Symmetric guard: a 14443-A tag must be refused by start_15693."""
import pytest
from pm3py.sim import NTAG213
s = SimSession()
s._port = MagicMock()
with pytest.raises(TypeError, match="ISO 15693"):
s.start_15693(NTAG213())