aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenryk Plötz <henryk@ploetzli.ch>2010-02-27 15:37:19 +0100
committerHenryk Plötz <henryk@ploetzli.ch>2010-02-27 15:37:19 +0100
commitd073fc662eb90beb672c8b367adbe9afa895fda5 (patch)
treec2ecd32013c8768abcb5fd424e70e88361a93728
parentf6f305317a34728bc22ef6952a299be930d13b37 (diff)
Implement the card request loop in connect() in the Smartcard_Reader base class and move all the gory details into _internal_connect to be implemented in the subclasses
-rw-r--r--readers.py53
1 files changed, 38 insertions, 15 deletions
diff --git a/readers.py b/readers.py
index c37e17c..cd1f949 100644
--- a/readers.py
+++ b/readers.py
@@ -13,10 +13,32 @@ class Smartcard_Reader(object):
return []
list_readers = classmethod(list_readers)
- def connect(self):
- "Create a connection to this reader"
+
+ _CONNECT_NO_CARD = object()
+ _CONNECT_MUTE_CARD = object()
+ _CONNECT_DONE = object()
+ def _internal_connect(self):
+ """Must implement the iterator protocol and yield
+ one of self._CONNECT_NO_CARD, self._CONNECT_MUTE_CARD or self._CONNECT_DONE.
+ The iterator will not be called again after yielding _CONNECT_DONE, so it must
+ clean itself up before that."""
raise NotImplementedError, "Please implement in a sub-class"
+ def connect(self):
+ have_card = False
+ printed = False
+ for result in self._internal_connect():
+ if result is self._CONNECT_DONE:
+ have_card = True
+ break
+ elif result is self._CONNECT_MUTE_CARD:
+ print "Card is mute or absent. Please retry."
+ elif result is self._CONNECT_NO_CARD:
+ if not printed:
+ print "Please insert card ..."
+ printed = True
+ return have_card
+
def get_ATR(self):
"Get the ATR of the inserted card as a binary string"
raise NotImplementedError, "Please implement in a sub-class"
@@ -38,12 +60,14 @@ class PCSC_Reader(Smartcard_Reader):
name = property(lambda self: self._name, None, None, "The human readable name of the reader")
def list_readers(cls):
- return [ (str(r), cls(r)) for r in smartcard.System.readers() ]
+ try:
+ return [ (str(r), cls(r)) for r in smartcard.System.readers() ]
+ except smartcard.pcsc.PCSCExceptions.EstablishContextException:
+ return []
list_readers = classmethod(list_readers)
- def connect(self):
+ def _internal_connect(self):
unpatched = False
- printed = False
while True:
try:
if not unpatched:
@@ -53,24 +77,23 @@ class PCSC_Reader(Smartcard_Reader):
self._cardservice = cardrequest.waitforcard()
self._cardservice.connection.connect()
- break
+ del cardrequest
+ yield self._CONNECT_DONE
except TypeError:
unpatched = True
except (KeyboardInterrupt, SystemExit):
raise
except smartcard.Exceptions.CardRequestException:
if sys.exc_info()[1].message.endswith("Command timeout."):
- if not printed:
- print "Please insert card ..."
- printed = True
+ yield self._CONNECT_NO_CARD
else:
raise
except smartcard.Exceptions.CardRequestTimeoutException:
- if not printed:
- print "Please insert card ..."
- printed = True
+ yield self._CONNECT_NO_CARD
except smartcard.Exceptions.NoCardException:
- print "Card is mute or absent. Please retry."
+ yield self._CONNECT_MUTE_CARD
+ except smartcard.Exceptions.CardConnectionException:
+ yield self._CONNECT_MUTE_CARD
def get_ATR(self):
return smartcard.util.toASCIIString(self._cardservice.connection.getATR())
@@ -148,10 +171,10 @@ class ACR122_Reader(Smartcard_Reader):
if ord(response[2]) > 0:
return True
- def connect(self):
- # FIXME Add loop or something similar to PCSC_Reader.connect
+ def _internal_connect(self):
self._parent.connect()
self.pn532_acquire_card()
+ yield self._CONNECT_DONE
def get_ATR(self):
# FIXME Properly implement for PC/SC version 2