aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenryk Plötz <henryk@ploetzli.ch>2010-03-03 01:38:53 +0100
committerHenryk Plötz <henryk@ploetzli.ch>2010-03-03 01:38:53 +0100
commitda261b13328e7c2a14b8dcaca5974415be786b97 (patch)
treed07ffd95c17789f9b2a2b233ad81b634d2f11c43
parentb27a1e034fd6124307ae69df31dfb8d96647ec27 (diff)
Move InListPassiveTarget response parsing to PN532_Response_InListPassiveTarget class
-rw-r--r--cards/pn532_card.py40
-rw-r--r--readers.py14
-rw-r--r--utils.py85
3 files changed, 91 insertions, 48 deletions
diff --git a/cards/pn532_card.py b/cards/pn532_card.py
index 659c9fc..6bff738 100644
--- a/cards/pn532_card.py
+++ b/cards/pn532_card.py
@@ -99,31 +99,27 @@ class PN532_Virtual_Card(Card):
return cmd
def pn532_parse_response_4B(self, response):
- response = map(ord, response)
- numtg = response[0]
- result = ["Targets detected: %i" % numtg]
- pos = 1
- last_pos = pos
+ r = utils.PN532_Response_InListPassiveTarget(data = response)
+ parse_ok = r.parse_result(self._last_baudrate_polled)
- while pos < len(response):
- if self._last_baudrate_polled == 0:
- s = "Target %i: ISO 14443-A, SENS_RES: %02X %02X, SEL_RES: %02X" % \
- ( response[pos], response[pos+1], response[pos+2], response[pos+3] )
- pos = pos + 4
- if response[pos] > 0:
- s = s+", NFCID (%02X bytes): %s" % (response[pos], " ".join(map(lambda a: "%02X" % a, response[pos+1:(pos+1+response[pos])])))
- pos = pos + response[pos]
- pos = pos + 1 # NFCID length does not count length byte
- if len(response) > pos and response[pos] > 0:
- s = s+", ATS (%02X bytes): %s" % (response[pos], " ".join(map(lambda a: "%02X" % a, response[pos:(pos+response[pos])])))
- pos = pos + response[pos]
- # ATS length does count length byte
+ result = ["Targets detected: %i" % len(r.targets)]
+
+ if not parse_ok:
+ result.append("Parse error, results unreliable")
+
+ for index, target in r.targets.items():
+ s = "Target %i: %s" % (index, target.type)
+ if target.type == utils.PN532_Target.TYPE_ISO14443A:
+ s = s + ", SENS_RES: %02X %02X, SEL_RES: %02X" % (
+ target.sens_res[0], target.sens_res[1], target.sel_res)
+ if len(target.nfcid) > 0:
+ s = s + ", NFCID (%i bytes): %s" % (
+ 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)
-
- if last_pos == pos:
- print "Implementation error, no advance, abort"
- break
return result
diff --git a/readers.py b/readers.py
index af95990..c06c049 100644
--- a/readers.py
+++ b/readers.py
@@ -162,17 +162,17 @@ class ACR122_Reader(Smartcard_Reader):
return "".join(response[:-2])
def pn532_acquire_card(self):
- response = self.pn532_transceive("\xd4\x04")
- if ord(response[4]) > 0:
+ # Turn antenna power off and on to forcefully reinitialize the card
+ 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
else:
- response = self.pn532_transceive("\xd4\x4a\x01\x00")
+ response = self.pn532_transceive("\xd4\x4a\x01\x03\x00")
if ord(response[2]) > 0:
return True
- else:
- response = self.pn532_transceive("\xd4\x4a\x01\x03\x00")
- if ord(response[2]) > 0:
- return True
def _internal_connect(self):
self._parent.connect()
diff --git a/utils.py b/utils.py
index b973e44..c187892 100644
--- a/utils.py
+++ b/utils.py
@@ -124,7 +124,7 @@ def _unformat_hexdump(dump):
def _make_byte_property(prop):
"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: delattr(self, "_"+prop),
"The %s attribute of the APDU" % prop)
@@ -177,7 +177,7 @@ class APDU(object):
setattr(self, name, value)
def _getdata(self):
- return self._data
+ return getattr(self, "_data", [])
def _setdata(self, value):
if isinstance(value, str):
self._data = "".join([e for e in value])
@@ -491,24 +491,30 @@ class PN532_Frame(APDU):
if m != -1:
matches[candidate] = m
- # Remove all candidates that don't have maximal 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
- # the first one.
- if len(candidates) > 0:
- c = candidates[0]
- if c != self.__class__:
- self.__class__ = c
+ if len(matches) > 0:
+ # Remove all candidates that don't have maximal 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
+ # the first one.
+ if len(candidates) > 0:
+ c = candidates[0]
+ if c != self.__class__:
+ self.__class__ = c
DIR = _make_byte_property("DIR"); dir = DIR
CMD = _make_byte_property("CMD"); cmd = CMD
def parse(self, data):
- self.dir = data[0]
- self.cmd = data[1]
- self.data = data[2:]
+ if len(data) > 0:
+ self.dir = data[0]
+
+ if len(data) > 1:
+ self.cmd = data[1]
+
+ if len(data) > 2:
+ self.data = data[2:]
def _format_fields(self):
fields = ["DIR", "CMD"]
@@ -518,13 +524,54 @@ class PN532_Frame(APDU):
return chr(self.cmd) + chr(self.dir) + self.data
class PN532_Command(PN532_Frame):
- MATCH_BY_dir = 0xd4
+ MATCH_BY_dir = _DEFAULT_DIR = 0xd4
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
-class PN532_Response_InListPassiveTarget(PN532_Frame):
- MATCH_BY_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
+
if __name__ == "__main__":