From bdca252fb00469fed288be239e29f57019a33194 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Thu, 9 Dec 2010 13:31:58 +0100 Subject: transport: Change transport api to allow for wait_for_card/connect/disconnect This way, we can re-use the same transport parameters for several cards for a future batch mode Signed-off-by: Sylvain Munaut --- pySim-prog.py | 3 +++ pySim/transport/__init__.py | 19 ++++++++++++++++ pySim/transport/pcsc.py | 23 +++++++++++++++---- pySim/transport/serial.py | 55 ++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/pySim-prog.py b/pySim-prog.py index b7fc793..df66b80 100755 --- a/pySim-prog.py +++ b/pySim-prog.py @@ -302,6 +302,9 @@ if __name__ == '__main__': sl = PcscSimLink(opts.pcsc_dev) scc = SimCardCommands(transport=sl) + print "Insert Card now" + sl.wait_for_card() + # Detect type if needed card = None ctypes = dict([(kls.name, kls) for kls in _cards_classes]) diff --git a/pySim/transport/__init__.py b/pySim/transport/__init__.py index c9715fc..dd04bba 100644 --- a/pySim/transport/__init__.py +++ b/pySim/transport/__init__.py @@ -23,6 +23,25 @@ class LinkBase(object): + def wait_for_card(self, timeout=None, newcardonly=False): + """wait_for_card(): Wait for a card and connect to it + + timeout : Maximum wait time (None=no timeout) + newcardonly : Should we wait for a new card, or an already + inserted one ? + """ + pass + + def connect(self): + """connect(): Connect to a card immediately + """ + pass + + def disconnect(self): + """disconnect(): Disconnect from card + """ + pass + def reset_card(self): """reset_card(): Resets the card (power down/up) """ diff --git a/pySim/transport/pcsc.py b/pySim/transport/pcsc.py index 5d92009..dc040c5 100644 --- a/pySim/transport/pcsc.py +++ b/pySim/transport/pcsc.py @@ -22,7 +22,8 @@ # along with this program. If not, see . # -from smartcard.Exceptions import NoCardException +from smartcard.CardRequest import CardRequest +from smartcard.Exceptions import NoCardException, CardRequestTimeoutException from smartcard.System import readers from pySim.exceptions import NoCardError @@ -34,15 +35,29 @@ class PcscSimLink(LinkBase): def __init__(self, reader_number=0): r = readers(); + self._reader = r[reader_number] + self._con = self._reader.createConnection() + + def __del__(self): + self._con.disconnect() + return + + def wait_for_card(self, timeout=None, newcardonly=False): + cr = CardRequest(readers=[self._reader], timeout=timeout, newcardonly=newcardonly) + try: + cr.waitforcard() + except CardRequestTimeoutException: + raise NoCardError() + self.connect() + + def connect(self): try: - self._con = r[reader_number].createConnection() self._con.connect() except NoCardException: raise NoCardError() - def __del__(self): + def disconnect(self): self._con.disconnect() - return def reset_card(self): self._con.disconnect() diff --git a/pySim/transport/serial.py b/pySim/transport/serial.py index d384146..825c458 100644 --- a/pySim/transport/serial.py +++ b/pySim/transport/serial.py @@ -47,16 +47,61 @@ class SerialSimLink(LinkBase): self._rst_pin = rst self._debug = debug - rv = self.reset_card() + def __del__(self): + self._sl.close() + + def wait_for_card(self, timeout=None, newcardonly=False): + # Direct try + existing = False + + try: + self.reset_card() + if not newcardonly: + return + else: + existing = True + except NoCardError: + pass + + # Poll ... + mt = time.time() + timeout if timeout is not None else None + pe = 0 + + while (mt is None) or (time.time() < mt): + try: + time.sleep(0.5) + self.reset_card() + if not existing: + return + except NoCardError: + existing = False + except ProtocolError: + if existing: + existing = False + else: + # Tolerate a couple of protocol error ... can happen if + # we try when the card is 'half' inserted + pe += 1 + if (pe > 2): + raise + + # Timed out ... + raise NoCardError() + + def connect(self): + self.reset_card() + + def disconnect(self): + pass # Nothing to do really ... + + def reset_card(self): + rv = self._reset_card() if rv == 0: raise NoCardError() elif rv < 0: raise ProtocolError() - def __del__(self): - self._sl.close() - - def reset_card(self): + def _reset_card(self): rst_meth_map = { 'rts': self._sl.setRTS, 'dtr': self._sl.setDTR, -- cgit v1.2.3