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 <tnt@246tNt.com>
This commit is contained in:
Sylvain Munaut 2010-12-09 13:31:58 +01:00
parent 9c8729a2d1
commit bdca252fb0
4 changed files with 93 additions and 11 deletions

View File

@ -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])

View File

@ -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)
"""

View File

@ -22,7 +22,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
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:

View File

@ -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,