Move InListPassiveTarget response parsing to PN532_Response_InListPassiveTarget class
This commit is contained in:
parent
b27a1e034f
commit
da261b1332
|
@ -99,32 +99,28 @@ class PN532_Virtual_Card(Card):
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def pn532_parse_response_4B(self, response):
|
def pn532_parse_response_4B(self, response):
|
||||||
response = map(ord, response)
|
r = utils.PN532_Response_InListPassiveTarget(data = response)
|
||||||
numtg = response[0]
|
parse_ok = r.parse_result(self._last_baudrate_polled)
|
||||||
result = ["Targets detected: %i" % numtg]
|
|
||||||
pos = 1
|
|
||||||
last_pos = pos
|
|
||||||
|
|
||||||
while pos < len(response):
|
result = ["Targets detected: %i" % len(r.targets)]
|
||||||
if self._last_baudrate_polled == 0:
|
|
||||||
s = "Target %i: ISO 14443-A, SENS_RES: %02X %02X, SEL_RES: %02X" % \
|
if not parse_ok:
|
||||||
( response[pos], response[pos+1], response[pos+2], response[pos+3] )
|
result.append("Parse error, results unreliable")
|
||||||
pos = pos + 4
|
|
||||||
if response[pos] > 0:
|
for index, target in r.targets.items():
|
||||||
s = s+", NFCID (%02X bytes): %s" % (response[pos], " ".join(map(lambda a: "%02X" % a, response[pos+1:(pos+1+response[pos])])))
|
s = "Target %i: %s" % (index, target.type)
|
||||||
pos = pos + response[pos]
|
if target.type == utils.PN532_Target.TYPE_ISO14443A:
|
||||||
pos = pos + 1 # NFCID length does not count length byte
|
s = s + ", SENS_RES: %02X %02X, SEL_RES: %02X" % (
|
||||||
if len(response) > pos and response[pos] > 0:
|
target.sens_res[0], target.sens_res[1], target.sel_res)
|
||||||
s = s+", ATS (%02X bytes): %s" % (response[pos], " ".join(map(lambda a: "%02X" % a, response[pos:(pos+response[pos])])))
|
if len(target.nfcid) > 0:
|
||||||
pos = pos + response[pos]
|
s = s + ", NFCID (%i bytes): %s" % (
|
||||||
# ATS length does count length byte
|
len(target.nfcid), " ".join(map(lambda a: "%02X" % a, target.nfcid)))
|
||||||
|
if len(target.ats) > 0:
|
||||||
|
s = s + ", ATS (%i bytes): %s" % (
|
||||||
|
len(target.ats), " ".join(map(lambda a: "%02X" % a, target.ats)))
|
||||||
|
|
||||||
result.append(s)
|
result.append(s)
|
||||||
|
|
||||||
if last_pos == pos:
|
|
||||||
print "Implementation error, no advance, abort"
|
|
||||||
break
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def can_handle(cls, reader):
|
def can_handle(cls, reader):
|
||||||
|
|
14
readers.py
14
readers.py
|
@ -162,17 +162,17 @@ class ACR122_Reader(Smartcard_Reader):
|
||||||
return "".join(response[:-2])
|
return "".join(response[:-2])
|
||||||
|
|
||||||
def pn532_acquire_card(self):
|
def pn532_acquire_card(self):
|
||||||
response = self.pn532_transceive("\xd4\x04")
|
# Turn antenna power off and on to forcefully reinitialize the card
|
||||||
if ord(response[4]) > 0:
|
self.pn532_transceive("\xd4\x32\x01\x00")
|
||||||
|
self.pn532_transceive("\xd4\x32\x01\x01")
|
||||||
|
|
||||||
|
response = self.pn532_transceive("\xd4\x4a\x01\x00")
|
||||||
|
if ord(response[2]) > 0:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
response = self.pn532_transceive("\xd4\x4a\x01\x00")
|
response = self.pn532_transceive("\xd4\x4a\x01\x03\x00")
|
||||||
if ord(response[2]) > 0:
|
if ord(response[2]) > 0:
|
||||||
return True
|
return True
|
||||||
else:
|
|
||||||
response = self.pn532_transceive("\xd4\x4a\x01\x03\x00")
|
|
||||||
if ord(response[2]) > 0:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _internal_connect(self):
|
def _internal_connect(self):
|
||||||
self._parent.connect()
|
self._parent.connect()
|
||||||
|
|
83
utils.py
83
utils.py
|
@ -124,7 +124,7 @@ def _unformat_hexdump(dump):
|
||||||
|
|
||||||
def _make_byte_property(prop):
|
def _make_byte_property(prop):
|
||||||
"Make a byte property(). This is meta code."
|
"Make a byte property(). This is meta code."
|
||||||
return property(lambda self: getattr(self, "_"+prop, 0),
|
return property(lambda self: getattr(self, "_"+prop, getattr(self, "_DEFAULT_"+prop, 0)),
|
||||||
lambda self, value: self._setbyte(prop, value),
|
lambda self, value: self._setbyte(prop, value),
|
||||||
lambda self: delattr(self, "_"+prop),
|
lambda self: delattr(self, "_"+prop),
|
||||||
"The %s attribute of the APDU" % prop)
|
"The %s attribute of the APDU" % prop)
|
||||||
|
@ -177,7 +177,7 @@ class APDU(object):
|
||||||
setattr(self, name, value)
|
setattr(self, name, value)
|
||||||
|
|
||||||
def _getdata(self):
|
def _getdata(self):
|
||||||
return self._data
|
return getattr(self, "_data", [])
|
||||||
def _setdata(self, value):
|
def _setdata(self, value):
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._data = "".join([e for e in value])
|
self._data = "".join([e for e in value])
|
||||||
|
@ -491,24 +491,30 @@ class PN532_Frame(APDU):
|
||||||
if m != -1:
|
if m != -1:
|
||||||
matches[candidate] = m
|
matches[candidate] = m
|
||||||
|
|
||||||
# Remove all candidates that don't have maximal score
|
if len(matches) > 0:
|
||||||
max_score = max(matches.values())
|
# Remove all candidates that don't have maximal score
|
||||||
candidates = [ k for k,v in matches.items() if v == max_score ]
|
max_score = max(matches.values())
|
||||||
|
candidates = [ k for k,v in matches.items() if v == max_score ]
|
||||||
|
|
||||||
# If there is still more than one candidate remaining, randomly choose
|
# If there is still more than one candidate remaining, randomly choose
|
||||||
# the first one.
|
# the first one.
|
||||||
if len(candidates) > 0:
|
if len(candidates) > 0:
|
||||||
c = candidates[0]
|
c = candidates[0]
|
||||||
if c != self.__class__:
|
if c != self.__class__:
|
||||||
self.__class__ = c
|
self.__class__ = c
|
||||||
|
|
||||||
DIR = _make_byte_property("DIR"); dir = DIR
|
DIR = _make_byte_property("DIR"); dir = DIR
|
||||||
CMD = _make_byte_property("CMD"); cmd = CMD
|
CMD = _make_byte_property("CMD"); cmd = CMD
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
self.dir = data[0]
|
if len(data) > 0:
|
||||||
self.cmd = data[1]
|
self.dir = data[0]
|
||||||
self.data = data[2:]
|
|
||||||
|
if len(data) > 1:
|
||||||
|
self.cmd = data[1]
|
||||||
|
|
||||||
|
if len(data) > 2:
|
||||||
|
self.data = data[2:]
|
||||||
|
|
||||||
def _format_fields(self):
|
def _format_fields(self):
|
||||||
fields = ["DIR", "CMD"]
|
fields = ["DIR", "CMD"]
|
||||||
|
@ -518,13 +524,54 @@ class PN532_Frame(APDU):
|
||||||
return chr(self.cmd) + chr(self.dir) + self.data
|
return chr(self.cmd) + chr(self.dir) + self.data
|
||||||
|
|
||||||
class PN532_Command(PN532_Frame):
|
class PN532_Command(PN532_Frame):
|
||||||
MATCH_BY_dir = 0xd4
|
MATCH_BY_dir = _DEFAULT_DIR = 0xd4
|
||||||
|
|
||||||
class PN532_Response(PN532_Frame):
|
class PN532_Response(PN532_Frame):
|
||||||
MATCH_BY_dir = 0xd5
|
MATCH_BY_dir = _DEFAULT_DIR = 0xd5
|
||||||
|
|
||||||
|
class PN532_Target(object):
|
||||||
|
TYPE_ISO14443A = "ISO 14443-A"
|
||||||
|
def __init__(self, type):
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
class PN532_Response_InListPassiveTarget(PN532_Response):
|
||||||
|
MATCH_BY_cmd = _DEFAULT_CMD = 0x4b
|
||||||
|
|
||||||
|
def parse_result(self, baudrate_polled):
|
||||||
|
response = map(ord, self.data)
|
||||||
|
self.targets = {}
|
||||||
|
pos = 1
|
||||||
|
last_pos = pos
|
||||||
|
|
||||||
|
while pos < len(response):
|
||||||
|
|
||||||
|
if baudrate_polled == 0:
|
||||||
|
target = PN532_Target(PN532_Target.TYPE_ISO14443A)
|
||||||
|
self.targets[response[pos]] = target
|
||||||
|
|
||||||
|
target.sens_res = response[(pos+1):(pos+3)]
|
||||||
|
target.sel_res = response[pos+3]
|
||||||
|
|
||||||
|
pos = pos + 4
|
||||||
|
if response[pos] > 0:
|
||||||
|
target.nfcid = response[pos+1:(pos+1+response[pos])]
|
||||||
|
pos = pos + response[pos]
|
||||||
|
else:
|
||||||
|
target.nfcid = []
|
||||||
|
pos = pos + 1 # NFCID length does not count length byte
|
||||||
|
|
||||||
|
if len(response) > pos and response[pos] > 0:
|
||||||
|
target.ats = response[pos:(pos+response[pos])]
|
||||||
|
pos = pos + response[pos]
|
||||||
|
else:
|
||||||
|
target.ats = []
|
||||||
|
# ATS length does count length byte
|
||||||
|
|
||||||
|
if last_pos == pos:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
class PN532_Response_InListPassiveTarget(PN532_Frame):
|
|
||||||
MATCH_BY_cmd = 0x4b
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in New Issue