feat: set_uid() with validation and random generation for 15693 tags
Tag15693.set_uid() now: - Accepts None (or no args) to generate a random valid UID with the correct IC-specific prefix (E0 + mfg + IC type) - Validates length (must be 8 bytes) - Warns on prefix mismatch (wrong IC type for product-specific tags) - Warns on non-NXP manufacturer code - Warns on missing E0 prefix
This commit is contained in:
@@ -128,6 +128,46 @@ class Tag15693(Transponder):
|
|||||||
random_bytes = os.urandom(8 - len(prefix))
|
random_bytes = os.urandom(8 - len(prefix))
|
||||||
return prefix + random_bytes
|
return prefix + random_bytes
|
||||||
|
|
||||||
|
def set_uid(self, uid: bytes | str | None = None) -> None:
|
||||||
|
"""Change the tag UID. Call sync() to push to firmware.
|
||||||
|
|
||||||
|
uid=None generates a random valid UID with the correct IC prefix.
|
||||||
|
Warns if the UID prefix doesn't match the expected IC type.
|
||||||
|
"""
|
||||||
|
import warnings
|
||||||
|
if uid is None:
|
||||||
|
self._uid = self._generate_uid()
|
||||||
|
self._uid_dirty = True
|
||||||
|
return
|
||||||
|
uid = self._parse_uid(uid)
|
||||||
|
if len(uid) != 8:
|
||||||
|
raise ValueError(f"UID must be 8 bytes, got {len(uid)}")
|
||||||
|
prefix = self._uid_prefix
|
||||||
|
if len(prefix) > 2 and uid[:len(prefix)] != prefix:
|
||||||
|
expected = prefix.hex().upper()
|
||||||
|
actual = uid[:len(prefix)].hex().upper()
|
||||||
|
cls_name = type(self).__name__
|
||||||
|
warnings.warn(
|
||||||
|
f"{cls_name}: UID prefix {actual} doesn't match expected {expected}. "
|
||||||
|
f"Phones/readers may not identify the IC type correctly. "
|
||||||
|
f"Use set_uid() with no args for a valid random UID.",
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
elif uid[:2] != b"\xE0\x04" and uid[:1] == b"\xE0":
|
||||||
|
warnings.warn(
|
||||||
|
f"UID manufacturer code {uid[1]:02X} is not NXP (04). "
|
||||||
|
f"Phones may not recognize this as an NXP tag.",
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
elif uid[:1] != b"\xE0":
|
||||||
|
warnings.warn(
|
||||||
|
f"UID must start with E0 (ISO 15693 IC manufacturer prefix). "
|
||||||
|
f"Got {uid[0]:02X}. This UID will not be recognized by readers.",
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
self._uid = uid
|
||||||
|
self._uid_dirty = True
|
||||||
|
|
||||||
def decode_trace(self, direction: int, payload: bytes) -> str | None:
|
def decode_trace(self, direction: int, payload: bytes) -> str | None:
|
||||||
return decode_15693(direction, payload)
|
return decode_15693(direction, payload)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user