aboutsummaryrefslogtreecommitdiffstats
path: root/pySim
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2010-12-09 13:31:58 +0100
committerSylvain Munaut <tnt@246tNt.com>2010-12-09 13:31:58 +0100
commitbdca252fb00469fed288be239e29f57019a33194 (patch)
treeeb3811c01f5fe7c40d9910c0e5e890406693fdde /pySim
parent9c8729a2d12f16920e5a4d37280d330356f51f39 (diff)
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>
Diffstat (limited to 'pySim')
-rw-r--r--pySim/transport/__init__.py19
-rw-r--r--pySim/transport/pcsc.py23
-rw-r--r--pySim/transport/serial.py55
3 files changed, 88 insertions, 9 deletions
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 <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,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,