diff options
author | Henryk Plötz <henryk@ploetzli.ch> | 2010-03-03 01:38:53 +0100 |
---|---|---|
committer | Henryk Plötz <henryk@ploetzli.ch> | 2010-03-03 01:38:53 +0100 |
commit | da261b13328e7c2a14b8dcaca5974415be786b97 (patch) | |
tree | d07ffd95c17789f9b2a2b233ad81b634d2f11c43 | |
parent | b27a1e034fd6124307ae69df31dfb8d96647ec27 (diff) |
Move InListPassiveTarget response parsing to PN532_Response_InListPassiveTarget class
-rw-r--r-- | cards/pn532_card.py | 40 | ||||
-rw-r--r-- | readers.py | 14 | ||||
-rw-r--r-- | utils.py | 85 |
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 @@ -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() @@ -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__": |