|
|
|
@ -139,7 +139,8 @@ class ACR122_Reader(Smartcard_Reader): |
|
|
|
|
def __init__(self, parent): |
|
|
|
|
self._parent = parent |
|
|
|
|
self._name = self._parent.name+"-RFID" |
|
|
|
|
self._last_ats = None |
|
|
|
|
self._current_target = None |
|
|
|
|
self._current_target_number = 0 |
|
|
|
|
|
|
|
|
|
def pn532_transceive_raw(self, command): |
|
|
|
|
c_apdu = "\xff\x00\x00\x00" + chr(len(command)) + command |
|
|
|
@ -173,13 +174,14 @@ class ACR122_Reader(Smartcard_Reader): |
|
|
|
|
r = utils.PN532_Frame(response) |
|
|
|
|
r.parse_result(0) |
|
|
|
|
if len(r.targets) > 0: |
|
|
|
|
self._last_ats = r.targets.values()[0].ats |
|
|
|
|
self._current_target_number, self._current_target = r.targets.items()[0] |
|
|
|
|
return True |
|
|
|
|
else: |
|
|
|
|
response = self.pn532_transceive("\xd4\x4a\x01\x03\x00") |
|
|
|
|
r = utils.PN532_Frame(response) |
|
|
|
|
r.parse_result(3) |
|
|
|
|
if len(r.targets) > 0: |
|
|
|
|
self._current_target_number, self._current_target = r.targets.items()[0] |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
def _internal_connect(self): |
|
|
|
@ -194,21 +196,37 @@ class ACR122_Reader(Smartcard_Reader): |
|
|
|
|
|
|
|
|
|
def get_ATR(self): |
|
|
|
|
# FIXME Properly implement for PC/SC version 2 |
|
|
|
|
if len(self._last_ats) == 0: |
|
|
|
|
return "\x3b\x80\x80\x01\x01" |
|
|
|
|
if self._current_target is None: return "" |
|
|
|
|
|
|
|
|
|
hist_bytes = [] |
|
|
|
|
|
|
|
|
|
if self._current_target.type == utils.PN532_Target.TYPE_ISO14443A: |
|
|
|
|
if len(self._current_target.ats) > 0: |
|
|
|
|
# Quick and dirty: Extract historical bytes from ATS |
|
|
|
|
ats = self._current_target.ats |
|
|
|
|
if ats[0] > 1: |
|
|
|
|
interface_bytes = 0 |
|
|
|
|
if ats[1] & 0x40: interface_bytes = interface_bytes + 1 |
|
|
|
|
if ats[1] & 0x20: interface_bytes = interface_bytes + 1 |
|
|
|
|
if ats[1] & 0x10: interface_bytes = interface_bytes + 1 |
|
|
|
|
hist_bytes = ats[ (2+interface_bytes): ] |
|
|
|
|
if len(hist_bytes) > 15: hist_bytes = hist_bytes[:15] |
|
|
|
|
else: |
|
|
|
|
return "\x3b\x80\x80\x01\x01" |
|
|
|
|
elif self._current_target.type == utils.PN532_Target.TYPE_ISO14443B: |
|
|
|
|
hist_bytes = self._current_target.atqb[5:9] + self._current_target.atqb[5:12] |
|
|
|
|
if len(self._current_target.attrib_res) > 0: |
|
|
|
|
hist_bytes.append(self._current_target.attrib_res[0] & 0xf0) |
|
|
|
|
else: |
|
|
|
|
hist_bytes.append(0) |
|
|
|
|
else: |
|
|
|
|
# Quick and dirty: Extract historical bytes from ATS |
|
|
|
|
hist_bytes = [] |
|
|
|
|
if self._last_ats[0] > 1: |
|
|
|
|
interface_bytes = 0 |
|
|
|
|
if self._last_ats[1] & 0x40: interface_bytes = interface_bytes + 1 |
|
|
|
|
if self._last_ats[1] & 0x20: interface_bytes = interface_bytes + 1 |
|
|
|
|
if self._last_ats[1] & 0x10: interface_bytes = interface_bytes + 1 |
|
|
|
|
hist_bytes = self._last_ats[ (2+interface_bytes): ] |
|
|
|
|
if len(hist_bytes) > 15: hist_bytes = hist_bytes[:15] |
|
|
|
|
atr = [0x3b, 0x80 + len(hist_bytes), 0x80, 0x01] + hist_bytes |
|
|
|
|
atr.append( reduce(lambda a,b: a ^ b, atr) ^ 0x3b ) |
|
|
|
|
return "".join(map(chr, atr)) |
|
|
|
|
return "" |
|
|
|
|
|
|
|
|
|
# The ISO 14443-4 A or -3 B code paths should have filled the hist_bytes list |
|
|
|
|
atr = [0x3b, 0x80 + len(hist_bytes), 0x80, 0x01] + hist_bytes |
|
|
|
|
atr.append( reduce(lambda a,b: a ^ b, atr) ^ 0x3b ) |
|
|
|
|
return "".join(map(chr, atr)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def transceive(self, data): |
|
|
|
|
# FIXME Properly determine target number |
|
|
|
|