feat: v0.3.8 — full access control stack, GRANTED working, NTAG424 ISO7816 read, PN532 driver
This commit is contained in:
34
pn532.py
34
pn532.py
@@ -302,7 +302,7 @@ class PN532_I2C:
|
||||
# 0. Poll for tag — activate it for InDataExchange
|
||||
uid = self.read_passive_target(timeout=timeout)
|
||||
if uid is None:
|
||||
return None
|
||||
return None, None, None
|
||||
utime.sleep_ms(100)
|
||||
|
||||
# 1. Select NDEF Application (D2 76 00 00 85 01 01)
|
||||
@@ -310,37 +310,37 @@ class PN532_I2C:
|
||||
0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00]
|
||||
resp = self._apdu(sel_app)
|
||||
if not resp:
|
||||
return None
|
||||
return None, None
|
||||
sw1, sw2 = resp[0], resp[1]
|
||||
if sw1 != 0x90:
|
||||
print('[pn532] select app failed: %02x %02x' % (sw1, sw2))
|
||||
return None
|
||||
return None, None
|
||||
|
||||
# 2. Select NDEF file (E1 04)
|
||||
sel_file = [0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x04]
|
||||
resp = self._apdu(sel_file)
|
||||
if not resp:
|
||||
return None
|
||||
return None, None
|
||||
sw1, sw2 = resp[0], resp[1]
|
||||
if sw1 != 0x90:
|
||||
print('[pn532] select file failed: %02x %02x' % (sw1, sw2))
|
||||
return None
|
||||
return None, None
|
||||
|
||||
# 3. Read first 2 bytes to get NDEF length
|
||||
read_len = [0x00, 0xB0, 0x00, 0x00, 0x02]
|
||||
resp = self._apdu(read_len)
|
||||
if not resp or len(resp) < 4:
|
||||
return None
|
||||
return None, None
|
||||
# resp = [len_hi][len_lo][SW1][SW2]
|
||||
if len(resp) < 4:
|
||||
return None
|
||||
return None, None
|
||||
sw1, sw2 = resp[2], resp[3]
|
||||
if sw1 != 0x90:
|
||||
print('[pn532] read len failed: %02x %02x' % (sw1, sw2))
|
||||
return None
|
||||
return None, None
|
||||
ndef_len = (resp[0] << 8) | resp[1]
|
||||
if ndef_len == 0:
|
||||
return None
|
||||
return None, None
|
||||
|
||||
# 4. Read NDEF data (max 200 bytes per read)
|
||||
ndef_data = bytearray()
|
||||
@@ -367,12 +367,12 @@ class PN532_I2C:
|
||||
remaining -= chunk
|
||||
|
||||
if not ndef_data:
|
||||
return None
|
||||
return None, None
|
||||
|
||||
# 5. Parse NDEF message
|
||||
# ndef_data = clean NDEF bytes, no response code prefix
|
||||
if len(ndef_data) < 3:
|
||||
return None
|
||||
return None, None
|
||||
|
||||
flags = ndef_data[0]
|
||||
type_len = ndef_data[1]
|
||||
@@ -395,19 +395,21 @@ class PN532_I2C:
|
||||
idx += type_len # skip type bytes
|
||||
|
||||
if idx + payload_len > len(ndef_data):
|
||||
return None
|
||||
return None, None
|
||||
|
||||
payload = ndef_data[idx:idx+payload_len]
|
||||
|
||||
# TextRecord: byte 0 = status (lang_len), then lang, then text
|
||||
if len(payload) < 1:
|
||||
return None
|
||||
return None, None
|
||||
lang_len = payload[0] & 0x3F
|
||||
text_start = 1 + lang_len
|
||||
if text_start > len(payload):
|
||||
return None
|
||||
return None, None
|
||||
|
||||
try:
|
||||
return bytes(payload[text_start:]).decode('utf-8')
|
||||
import ubinascii as _ub
|
||||
uid_hex = _ub.hexlify(uid).decode()
|
||||
return uid_hex, bytes(payload[text_start:]).decode('utf-8')
|
||||
except Exception:
|
||||
return None
|
||||
return None, None
|
||||
Reference in New Issue
Block a user