first init
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
"""The CardConnection abstract class manages connections with a card and
|
||||
apdu transmission.
|
||||
|
||||
__author__ = "https://www.gemalto.com/"
|
||||
|
||||
Copyright 2001-2012 gemalto
|
||||
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
|
||||
|
||||
This file is part of pyscard.
|
||||
|
||||
pyscard is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
pyscard is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with pyscard; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
from smartcard.CardConnectionEvent import CardConnectionEvent
|
||||
from smartcard.Observer import Observable
|
||||
|
||||
|
||||
class CardConnection(Observable):
|
||||
"""Card connection abstract class."""
|
||||
|
||||
T0_protocol = 0x00000001
|
||||
""" protocol T=0 """
|
||||
|
||||
T1_protocol = 0x00000002
|
||||
""" protocol T=1 """
|
||||
|
||||
RAW_protocol = 0x00010000
|
||||
""" protocol RAW (direct access to the reader) """
|
||||
|
||||
T15_protocol = 0x00000008
|
||||
""" protocol T=15 """
|
||||
|
||||
def __init__(self, reader):
|
||||
"""Construct a new card connection.
|
||||
|
||||
@param reader: name of the reader in which the smartcard to connect
|
||||
to is located.
|
||||
"""
|
||||
Observable.__init__(self)
|
||||
self.reader = reader
|
||||
""" reader name """
|
||||
self.errorcheckingchain = None
|
||||
""" see L{setErrorCheckingChain} """
|
||||
self.defaultprotocol = CardConnection.T0_protocol | CardConnection.T1_protocol
|
||||
""" see L{setProtocol} and L{getProtocol} """
|
||||
|
||||
def __del__(self):
|
||||
"""Connect to card."""
|
||||
|
||||
def addSWExceptionToFilter(self, exClass):
|
||||
"""Add a status word exception class to be filtered.
|
||||
|
||||
@param exClass: the class to filter, e.g.
|
||||
L{smartcard.sw.SWExceptions.WarningProcessingException}
|
||||
|
||||
Filtered exceptions will not be raised when encountered in the
|
||||
error checking chain."""
|
||||
if self.errorcheckingchain is not None:
|
||||
self.errorcheckingchain[0].addFilterException(exClass)
|
||||
|
||||
def addObserver(self, observer):
|
||||
"""Add a L{CardConnection} observer."""
|
||||
Observable.addObserver(self, observer)
|
||||
|
||||
def deleteObserver(self, observer):
|
||||
"""Remove a L{CardConnection} observer."""
|
||||
Observable.deleteObserver(self, observer)
|
||||
|
||||
def connect(self, protocol=None, mode=None, disposition=None):
|
||||
"""Connect to card.
|
||||
@param protocol: a bit mask of the protocols to use, from
|
||||
L{CardConnection.T0_protocol}, L{CardConnection.T1_protocol},
|
||||
L{CardConnection.RAW_protocol}, L{CardConnection.T15_protocol}
|
||||
|
||||
@param mode: C{smartcard.scard.SCARD_SHARE_SHARED} (default),
|
||||
C{smartcard.scard.SCARD_SHARE_EXCLUSIVE} or
|
||||
C{smartcard.scard.SCARD_SHARE_DIRECT}
|
||||
|
||||
@param disposition: C{smartcard.scard.SCARD_LEAVE_CARD}
|
||||
(default), C{smartcard.scard.SCARD_RESET_CARD},
|
||||
C{smartcard.scard.SCARD_UNPOWER_CARD} or
|
||||
C{smartcard.scard.SCARD_EJECT_CARD}
|
||||
"""
|
||||
# pylint: disable=unused-argument
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(self, CardConnectionEvent("connect"))
|
||||
|
||||
def reconnect(self, protocol=None, mode=None, disposition=None):
|
||||
"""Reconnect to card.
|
||||
@param protocol: a bit mask of the protocols to use, from
|
||||
L{CardConnection.T0_protocol}, L{CardConnection.T1_protocol},
|
||||
L{CardConnection.RAW_protocol}, L{CardConnection.T15_protocol}
|
||||
|
||||
@param mode: C{smartcard.scard.SCARD_SHARE_SHARED} (default),
|
||||
C{smartcard.scard.SCARD_SHARE_EXCLUSIVE} or
|
||||
C{smartcard.scard.SCARD_SHARE_DIRECT}
|
||||
|
||||
@param disposition: C{smartcard.scard.SCARD_LEAVE_CARD},
|
||||
C{smartcard.scard.SCARD_RESET_CARD} (default),
|
||||
C{smartcard.scard.SCARD_UNPOWER_CARD} or
|
||||
C{smartcard.scard.SCARD_EJECT_CARD}
|
||||
"""
|
||||
# pylint: disable=unused-argument
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(self, CardConnectionEvent("reconnect"))
|
||||
|
||||
def disconnect(self):
|
||||
"""Disconnect from card."""
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(self, CardConnectionEvent("disconnect"))
|
||||
|
||||
def release(self):
|
||||
"""Release the context."""
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(self, CardConnectionEvent("release"))
|
||||
|
||||
def getATR(self):
|
||||
"""Return card ATR"""
|
||||
|
||||
def getProtocol(self):
|
||||
"""Return bit mask for the protocol of connection, or None if no
|
||||
protocol set. The return value is a bit mask of
|
||||
L{CardConnection.T0_protocol}, L{CardConnection.T1_protocol},
|
||||
L{CardConnection.RAW_protocol}, L{CardConnection.T15_protocol}
|
||||
"""
|
||||
return self.defaultprotocol
|
||||
|
||||
def getReader(self):
|
||||
"""Return card connection reader"""
|
||||
return self.reader
|
||||
|
||||
def setErrorCheckingChain(self, errorcheckingchain):
|
||||
"""Add an error checking chain.
|
||||
@param errorcheckingchain: a L{smartcard.sw.ErrorCheckingChain}
|
||||
object The error checking strategies in errorchecking chain will
|
||||
be tested with each received response APDU, and a
|
||||
L{smartcard.sw.SWExceptions.SWException} will be raised upon
|
||||
error."""
|
||||
self.errorcheckingchain = errorcheckingchain
|
||||
|
||||
def setProtocol(self, protocol):
|
||||
"""Set protocol for card connection.
|
||||
@param protocol: a bit mask of L{CardConnection.T0_protocol},
|
||||
L{CardConnection.T1_protocol}, L{CardConnection.RAW_protocol},
|
||||
L{CardConnection.T15_protocol}
|
||||
|
||||
>>> setProtocol(CardConnection.T1_protocol | CardConnection.T0_protocol)
|
||||
"""
|
||||
self.defaultprotocol = protocol
|
||||
|
||||
def transmit(self, command, protocol=None):
|
||||
"""Transmit an apdu. Internally calls L{doTransmit()} class method
|
||||
and notify observers upon command/response APDU events.
|
||||
Subclasses must override the L{doTransmit()} class method.
|
||||
|
||||
@param command: list of bytes to transmit
|
||||
|
||||
@param protocol: the transmission protocol, from
|
||||
L{CardConnection.T0_protocol},
|
||||
L{CardConnection.T1_protocol}, or
|
||||
L{CardConnection.RAW_protocol}
|
||||
"""
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(
|
||||
self, CardConnectionEvent("command", [command, protocol])
|
||||
)
|
||||
data, sw1, sw2 = self.doTransmit(command, protocol)
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(
|
||||
self, CardConnectionEvent("response", [data, sw1, sw2])
|
||||
)
|
||||
if self.errorcheckingchain is not None:
|
||||
self.errorcheckingchain[0](data, sw1, sw2)
|
||||
return data, sw1, sw2
|
||||
|
||||
def doTransmit(self, command, protocol):
|
||||
"""Performs the command APDU transmission.
|
||||
|
||||
Subclasses must override this method for implementing apdu
|
||||
transmission."""
|
||||
# pylint: disable=unused-argument
|
||||
return [], 0, 0
|
||||
|
||||
def control(self, controlCode, command=None):
|
||||
"""Send a control command and buffer. Internally calls
|
||||
L{doControl()} class method and notify observers upon
|
||||
command/response events. Subclasses must override the
|
||||
L{doControl()} class method.
|
||||
|
||||
@param controlCode: command code
|
||||
|
||||
@param command: list of bytes to transmit
|
||||
"""
|
||||
if command is None:
|
||||
command = []
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(
|
||||
self, CardConnectionEvent("command", [controlCode, command])
|
||||
)
|
||||
data = self.doControl(controlCode, command)
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(self, CardConnectionEvent("response", data))
|
||||
if self.errorcheckingchain is not None:
|
||||
self.errorcheckingchain[0](data)
|
||||
return data
|
||||
|
||||
def doControl(self, controlCode, command):
|
||||
"""Performs the command control.
|
||||
|
||||
Subclasses must override this method for implementing control."""
|
||||
# pylint: disable=unused-argument
|
||||
return []
|
||||
|
||||
def getAttrib(self, attribId):
|
||||
"""return the requested attribute
|
||||
|
||||
@param attribId: attribute id like
|
||||
C{smartcard.scard.SCARD_ATTR_VENDOR_NAME}
|
||||
"""
|
||||
Observable.setChanged(self)
|
||||
Observable.notifyObservers(self, CardConnectionEvent("attrib", [attribId]))
|
||||
data = self.doGetAttrib(attribId)
|
||||
if self.errorcheckingchain is not None:
|
||||
self.errorcheckingchain[0](data)
|
||||
return data
|
||||
|
||||
def doGetAttrib(self, attribId):
|
||||
"""Performs the command get attrib.
|
||||
|
||||
Subclasses must override this method for implementing get attrib."""
|
||||
# pylint: disable=unused-argument
|
||||
return []
|
||||
|
||||
def __enter__(self):
|
||||
"""Enter the runtime context."""
|
||||
return self
|
||||
|
||||
def __exit__(self, e_type, value, traceback):
|
||||
"""Exit the runtime context trying to disconnect."""
|
||||
self.disconnect()
|
||||
Reference in New Issue
Block a user