Add generic response chaining capability
This commit is contained in:
parent
2cc37817d7
commit
20b8d8167e
|
@ -147,10 +147,16 @@ class Card:
|
||||||
def _send_with_retry(self, apdu):
|
def _send_with_retry(self, apdu):
|
||||||
result = self._real_send(apdu)
|
result = self._real_send(apdu)
|
||||||
|
|
||||||
if self.check_sw(result.sw, self.PURPOSE_GET_RESPONSE):
|
while self.check_sw(result.sw, self.PURPOSE_GET_RESPONSE):
|
||||||
## Need to call GetResponse
|
## Need to call GetResponse
|
||||||
gr_apdu = self.COMMAND_GET_RESPONSE
|
gr_apdu = self.COMMAND_GET_RESPONSE
|
||||||
result = self._real_send(gr_apdu)
|
tmp = self._real_send(gr_apdu)
|
||||||
|
|
||||||
|
if not callable(result.append):
|
||||||
|
result = tmp
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
result = result.append(tmp)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
@ -36,3 +36,12 @@ class APDUCase1Tests(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(self.a4.render(), a4_2.render())
|
self.assertEqual(self.a4.render(), a4_2.render())
|
||||||
|
|
||||||
|
class APDUChainTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def testChain(self):
|
||||||
|
a = utils.R_APDU("abcd\x61\x04")
|
||||||
|
b = utils.R_APDU("efgh\x90\x00")
|
||||||
|
|
||||||
|
c = a.append(b)
|
||||||
|
|
||||||
|
self.assertEqual("abcdefgh\x90\x00", c.render())
|
||||||
|
|
7
utils.py
7
utils.py
|
@ -224,6 +224,10 @@ class Transmission_Frame(object):
|
||||||
parts.append("data=%r" % self.data)
|
parts.append("data=%r" % self.data)
|
||||||
|
|
||||||
return "%s(%s)" % (self.__class__.__name__, ", ".join(parts))
|
return "%s(%s)" % (self.__class__.__name__, ", ".join(parts))
|
||||||
|
|
||||||
|
# Stub for implementation in subclasses
|
||||||
|
# Semantics should be: c=a.append(b) <=> c.data == a.data + b.data and c.status == b.status
|
||||||
|
append = None
|
||||||
|
|
||||||
class Command_Frame(Transmission_Frame):
|
class Command_Frame(Transmission_Frame):
|
||||||
pass
|
pass
|
||||||
|
@ -472,6 +476,9 @@ class R_APDU(Response_Frame,APDU):
|
||||||
def render(self):
|
def render(self):
|
||||||
"Return this APDU as a binary string"
|
"Return this APDU as a binary string"
|
||||||
return self.data + self.sw
|
return self.data + self.sw
|
||||||
|
|
||||||
|
def append(self, other):
|
||||||
|
return R_APDU(self.data + other.data + other.sw)
|
||||||
|
|
||||||
APDU.COMMAND_CLASS = C_APDU
|
APDU.COMMAND_CLASS = C_APDU
|
||||||
APDU.RESPONSE_CLASS = R_APDU
|
APDU.RESPONSE_CLASS = R_APDU
|
||||||
|
|
Loading…
Reference in New Issue