diff --git a/pySim-prog.py b/pySim-prog.py index b7fc7938..df66b80d 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 c9715fcd..dd04bbad 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 5d920092..dc040c58 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,16 +35,30 @@ class PcscSimLink(LinkBase): def __init__(self, reader_number=0): r = readers(); - try: - self._con = r[reader_number].createConnection() - self._con.connect() - except NoCardException: - raise NoCardError() + 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.connect() + except NoCardException: + raise NoCardError() + + def disconnect(self): + self._con.disconnect() + def reset_card(self): self._con.disconnect() try: diff --git a/pySim/transport/serial.py b/pySim/transport/serial.py index d384146a..825c4585 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,