diff --git a/cards/generic_card.py b/cards/generic_card.py index 64d4bcb..37e3a0a 100644 --- a/cards/generic_card.py +++ b/cards/generic_card.py @@ -147,10 +147,16 @@ class Card: def _send_with_retry(self, 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 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 diff --git a/tests/utilstest.py b/tests/utilstest.py index 65b74b6..42d34f4 100644 --- a/tests/utilstest.py +++ b/tests/utilstest.py @@ -36,3 +36,12 @@ class APDUCase1Tests(unittest.TestCase): 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()) diff --git a/utils.py b/utils.py index e68007f..00533dc 100644 --- a/utils.py +++ b/utils.py @@ -224,6 +224,10 @@ class Transmission_Frame(object): parts.append("data=%r" % self.data) 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): pass @@ -472,6 +476,9 @@ class R_APDU(Response_Frame,APDU): def render(self): "Return this APDU as a binary string" return self.data + self.sw + + def append(self, other): + return R_APDU(self.data + other.data + other.sw) APDU.COMMAND_CLASS = C_APDU APDU.RESPONSE_CLASS = R_APDU