1 """PCSCCardConnection class manages connections thru a PCSC reader.
2
3 __author__ = "http://www.gemalto.com"
4
5 Copyright 2001-2011 gemalto
6 Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
7
8 This file is part of pyscard.
9
10 pyscard is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14
15 pyscard is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with pyscard; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 """
24
25 from smartcard.CardConnection import CardConnection
26 from smartcard.Exceptions import CardConnectionException, NoCardException
27 from smartcard.Observer import Observable
28
29 from smartcard.scard import *
30
31
45
46
58
59 dictProtocolHeader = {SCARD_PCI_T0: 'T0', SCARD_PCI_T1: 'T1',
60 SCARD_PCI_RAW: 'RAW'}
61 dictProtocol = {SCARD_PROTOCOL_T0: 'T0', SCARD_PROTOCOL_T1: 'T1',
62 SCARD_PROTOCOL_RAW: 'RAW', SCARD_PROTOCOL_T15: 'T15',
63 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1: 'T0 or T1'}
64
65
67 """PCSCCard connection class. Handles connection with a card thru a
68 PCSC reader."""
69
80
90
91 - def connect(self, protocol=None, mode=None, disposition=None):
124
141
151
153 """Transmit an apdu to the card and return response apdu.
154
155 bytes: command apdu to transmit (list of bytes)
156
157 protocol: the transmission protocol, from CardConnection.T0_protocol, CardConnection.T1_protocol,
158 or CardConnection.RAW_protocol
159
160 return: a tuple (response, sw1, sw2) where
161 sw1 is status word 1, e.g. 0x90
162 sw2 is status word 2, e.g. 0x1A
163 response are the response bytes excluding status words
164 """
165 if None == protocol:
166 protocol = self.getProtocol()
167 CardConnection.doTransmit(self, bytes, protocol)
168 pcscprotocolheader = translateprotocolheader(protocol)
169 if 0 == pcscprotocolheader:
170 raise CardConnectionException('Invalid protocol in transmit: must be CardConnection.T0_protocol, CardConnection.T1_protocol, or CardConnection.RAW_protocol')
171 if None == self.hcard:
172 raise CardConnectionException('Card not connected')
173 hresult, response = SCardTransmit(self.hcard, pcscprotocolheader, bytes)
174 if hresult != 0:
175 raise CardConnectionException('Failed to transmit with protocol ' + dictProtocolHeader[pcscprotocolheader] + '. ' + SCardGetErrorMessage(hresult))
176
177 sw1 = (response[-2] + 256) % 256
178 sw2 = (response[-1] + 256) % 256
179
180 data = map(lambda x: (x + 256) % 256, response[:-2])
181 return data, sw1, sw2
182
184 """Transmit a control command to the reader and return response.
185
186 controlCode: control command
187
188 bytes: command data to transmit (list of bytes)
189
190 return: response are the response bytes (if any)
191 """
192 CardConnection.doControl(self, controlCode, bytes)
193 hresult, response = SCardControl(self.hcard, controlCode, bytes)
194 if hresult != 0:
195 raise CardConnectionException('Failed to control ' + SCardGetErrorMessage(hresult))
196
197 data = map(lambda x: (x + 256) % 256, response)
198 return data
199
200 if __name__ == '__main__':
201 """Small sample illustrating the use of CardConnection."""
202 SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]
203 DF_TELECOM = [0x7F, 0x10]
204 from smartcard.pcsc.PCSCReader import readers
205 cc = readers()[0].createConnection()
206 cc.connect()
207 print "%r %x %x" % cc.transmit(SELECT + DF_TELECOM)
208
209 print cc.control(0, [])
210