diff options
author | Henryk Plötz <henryk@ploetzli.ch> | 2010-10-15 17:58:54 +0200 |
---|---|---|
committer | Henryk Plötz <henryk@ploetzli.ch> | 2010-10-15 17:58:54 +0200 |
commit | 20b8d8167ee864c88287412da224d93c17381a08 (patch) | |
tree | 6da5a168fcc5244d168e086be4070c561d89ea21 | |
parent | 2cc37817d7fbc0f2f10cf09090f9ac06f6bbbc7e (diff) |
Add generic response chaining capability
-rw-r--r-- | cards/generic_card.py | 10 | ||||
-rw-r--r-- | tests/utilstest.py | 9 | ||||
-rw-r--r-- | utils.py | 7 |
3 files changed, 24 insertions, 2 deletions
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()) @@ -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 |