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
This commit is contained in:
parent
f6f305317a
commit
d073fc662e
51
readers.py
51
readers.py
|
@ -13,10 +13,32 @@ class Smartcard_Reader(object):
|
||||||
return []
|
return []
|
||||||
list_readers = classmethod(list_readers)
|
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"
|
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):
|
def get_ATR(self):
|
||||||
"Get the ATR of the inserted card as a binary string"
|
"Get the ATR of the inserted card as a binary string"
|
||||||
raise NotImplementedError, "Please implement in a sub-class"
|
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")
|
name = property(lambda self: self._name, None, None, "The human readable name of the reader")
|
||||||
|
|
||||||
def list_readers(cls):
|
def list_readers(cls):
|
||||||
|
try:
|
||||||
return [ (str(r), cls(r)) for r in smartcard.System.readers() ]
|
return [ (str(r), cls(r)) for r in smartcard.System.readers() ]
|
||||||
|
except smartcard.pcsc.PCSCExceptions.EstablishContextException:
|
||||||
|
return []
|
||||||
list_readers = classmethod(list_readers)
|
list_readers = classmethod(list_readers)
|
||||||
|
|
||||||
def connect(self):
|
def _internal_connect(self):
|
||||||
unpatched = False
|
unpatched = False
|
||||||
printed = False
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
if not unpatched:
|
if not unpatched:
|
||||||
|
@ -53,24 +77,23 @@ class PCSC_Reader(Smartcard_Reader):
|
||||||
|
|
||||||
self._cardservice = cardrequest.waitforcard()
|
self._cardservice = cardrequest.waitforcard()
|
||||||
self._cardservice.connection.connect()
|
self._cardservice.connection.connect()
|
||||||
break
|
del cardrequest
|
||||||
|
yield self._CONNECT_DONE
|
||||||
except TypeError:
|
except TypeError:
|
||||||
unpatched = True
|
unpatched = True
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except (KeyboardInterrupt, SystemExit):
|
||||||
raise
|
raise
|
||||||
except smartcard.Exceptions.CardRequestException:
|
except smartcard.Exceptions.CardRequestException:
|
||||||
if sys.exc_info()[1].message.endswith("Command timeout."):
|
if sys.exc_info()[1].message.endswith("Command timeout."):
|
||||||
if not printed:
|
yield self._CONNECT_NO_CARD
|
||||||
print "Please insert card ..."
|
|
||||||
printed = True
|
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
except smartcard.Exceptions.CardRequestTimeoutException:
|
except smartcard.Exceptions.CardRequestTimeoutException:
|
||||||
if not printed:
|
yield self._CONNECT_NO_CARD
|
||||||
print "Please insert card ..."
|
|
||||||
printed = True
|
|
||||||
except smartcard.Exceptions.NoCardException:
|
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):
|
def get_ATR(self):
|
||||||
return smartcard.util.toASCIIString(self._cardservice.connection.getATR())
|
return smartcard.util.toASCIIString(self._cardservice.connection.getATR())
|
||||||
|
@ -148,10 +171,10 @@ class ACR122_Reader(Smartcard_Reader):
|
||||||
if ord(response[2]) > 0:
|
if ord(response[2]) > 0:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def connect(self):
|
def _internal_connect(self):
|
||||||
# FIXME Add loop or something similar to PCSC_Reader.connect
|
|
||||||
self._parent.connect()
|
self._parent.connect()
|
||||||
self.pn532_acquire_card()
|
self.pn532_acquire_card()
|
||||||
|
yield self._CONNECT_DONE
|
||||||
|
|
||||||
def get_ATR(self):
|
def get_ATR(self):
|
||||||
# FIXME Properly implement for PC/SC version 2
|
# FIXME Properly implement for PC/SC version 2
|
||||||
|
|
Loading…
Reference in New Issue