blob: e3f2546f4760cb28f1b741ed3a51a8633ba2f5c2 [file] [log] [blame]
Sylvain Munaut76504e02010-12-07 00:24:32 +01001# -*- coding: utf-8 -*-
2
Sylvain Munaut76504e02010-12-07 00:24:32 +01003# Copyright (C) 2009-2010 Sylvain Munaut <tnt@246tNt.com>
4# Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19
Vadim Yanitskiyfa617ac2020-02-26 22:33:08 +070020from smartcard.CardConnection import CardConnection
Sylvain Munautbdca2522010-12-09 13:31:58 +010021from smartcard.CardRequest import CardRequest
Harald Welte2db843e2021-05-21 22:51:28 +020022from smartcard.Exceptions import NoCardException, CardRequestTimeoutException, CardConnectionException, CardConnectionException
Sylvain Munaut76504e02010-12-07 00:24:32 +010023from smartcard.System import readers
Sylvain Munaut76504e02010-12-07 00:24:32 +010024
Harald Welte2db843e2021-05-21 22:51:28 +020025from pySim.exceptions import NoCardError, ProtocolError, ReaderError
Sylvain Munaute7c15cd2010-12-07 10:01:55 +010026from pySim.transport import LinkBase
Sylvain Munaut76504e02010-12-07 00:24:32 +010027from pySim.utils import h2i, i2h
28
29
Sylvain Munaute7c15cd2010-12-07 10:01:55 +010030class PcscSimLink(LinkBase):
Harald Weltec91085e2022-02-10 18:05:45 +010031 """ pySim: PCSC reader transport link."""
Sylvain Munaut76504e02010-12-07 00:24:32 +010032
Harald Weltec91085e2022-02-10 18:05:45 +010033 def __init__(self, reader_number: int = 0, **kwargs):
34 super().__init__(**kwargs)
35 r = readers()
36 if reader_number >= len(r):
Vadim Yanitskiye6b86872022-04-21 16:50:25 +030037 raise ReaderError('No reader found for number %d' % reader_number)
Harald Weltec91085e2022-02-10 18:05:45 +010038 self._reader = r[reader_number]
39 self._con = self._reader.createConnection()
Sylvain Munaut76504e02010-12-07 00:24:32 +010040
Harald Weltec91085e2022-02-10 18:05:45 +010041 def __del__(self):
42 try:
43 # FIXME: this causes multiple warnings in Python 3.5.3
44 self._con.disconnect()
45 except:
46 pass
47 return
Sylvain Munaut76504e02010-12-07 00:24:32 +010048
Harald Weltec91085e2022-02-10 18:05:45 +010049 def wait_for_card(self, timeout: int = None, newcardonly: bool = False):
50 cr = CardRequest(readers=[self._reader],
51 timeout=timeout, newcardonly=newcardonly)
52 try:
53 cr.waitforcard()
54 except CardRequestTimeoutException:
55 raise NoCardError()
56 self.connect()
Sylvain Munautbdca2522010-12-09 13:31:58 +010057
Harald Weltec91085e2022-02-10 18:05:45 +010058 def connect(self):
59 try:
60 # To avoid leakage of resources, make sure the reader
61 # is disconnected
62 self.disconnect()
Philipp Maier8bf21252021-09-22 15:30:21 +020063
Harald Weltec91085e2022-02-10 18:05:45 +010064 # Explicitly select T=0 communication protocol
65 self._con.connect(CardConnection.T0_protocol)
66 except CardConnectionException:
67 raise ProtocolError()
68 except NoCardException:
69 raise NoCardError()
Sylvain Munautbdca2522010-12-09 13:31:58 +010070
Harald Weltec91085e2022-02-10 18:05:45 +010071 def get_atr(self):
72 return self._con.getATR()
Alexander Chemerisd2d660a2017-07-18 16:52:25 +030073
Harald Weltec91085e2022-02-10 18:05:45 +010074 def disconnect(self):
75 self._con.disconnect()
Sylvain Munautbdca2522010-12-09 13:31:58 +010076
Harald Weltec91085e2022-02-10 18:05:45 +010077 def reset_card(self):
78 self.disconnect()
79 self.connect()
80 return 1
Sylvain Munaut76504e02010-12-07 00:24:32 +010081
Harald Weltec91085e2022-02-10 18:05:45 +010082 def _send_apdu_raw(self, pdu):
Sylvain Munaut76504e02010-12-07 00:24:32 +010083
Harald Weltec91085e2022-02-10 18:05:45 +010084 apdu = h2i(pdu)
Sylvain Munaut76504e02010-12-07 00:24:32 +010085
Harald Weltec91085e2022-02-10 18:05:45 +010086 data, sw1, sw2 = self._con.transmit(apdu)
Sylvain Munaut76504e02010-12-07 00:24:32 +010087
Harald Weltec91085e2022-02-10 18:05:45 +010088 sw = [sw1, sw2]
Sylvain Munaut76504e02010-12-07 00:24:32 +010089
Harald Weltec91085e2022-02-10 18:05:45 +010090 # Return value
91 return i2h(data), i2h(sw)