mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-03-26 15:28:35 +03:00
pySim/transport: More type annotations
Change-Id: I62e081271e3a579851a588a4ed7282017e56f852
This commit is contained in:
@@ -6,10 +6,11 @@
|
|||||||
import abc
|
import abc
|
||||||
import argparse
|
import argparse
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple
|
||||||
|
from construct import Construct
|
||||||
|
|
||||||
from pySim.exceptions import *
|
from pySim.exceptions import *
|
||||||
from pySim.construct import filter_dict
|
from pySim.construct import filter_dict
|
||||||
from pySim.utils import sw_match, b2h, h2b, i2h, Hexstr
|
from pySim.utils import sw_match, b2h, h2b, i2h, Hexstr, SwHexstr, SwMatchstr
|
||||||
from pySim.cat import ProactiveCommand, CommandDetails, DeviceIdentities, Result
|
from pySim.cat import ProactiveCommand, CommandDetails, DeviceIdentities, Result
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -60,14 +61,14 @@ class ProactiveHandler(abc.ABC):
|
|||||||
class LinkBase(abc.ABC):
|
class LinkBase(abc.ABC):
|
||||||
"""Base class for link/transport to card."""
|
"""Base class for link/transport to card."""
|
||||||
|
|
||||||
def __init__(self, sw_interpreter=None, apdu_tracer=None,
|
def __init__(self, sw_interpreter=None, apdu_tracer: Optional[ApduTracer]=None,
|
||||||
proactive_handler: Optional[ProactiveHandler]=None):
|
proactive_handler: Optional[ProactiveHandler]=None):
|
||||||
self.sw_interpreter = sw_interpreter
|
self.sw_interpreter = sw_interpreter
|
||||||
self.apdu_tracer = apdu_tracer
|
self.apdu_tracer = apdu_tracer
|
||||||
self.proactive_handler = proactive_handler
|
self.proactive_handler = proactive_handler
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def _send_apdu_raw(self, pdu: str) -> Tuple[str, str]:
|
def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, Hexstr]:
|
||||||
"""Implementation specific method for sending the PDU."""
|
"""Implementation specific method for sending the PDU."""
|
||||||
|
|
||||||
def set_sw_interpreter(self, interp):
|
def set_sw_interpreter(self, interp):
|
||||||
@@ -75,7 +76,7 @@ class LinkBase(abc.ABC):
|
|||||||
self.sw_interpreter = interp
|
self.sw_interpreter = interp
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def wait_for_card(self, timeout: int = None, newcardonly: bool = False):
|
def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False):
|
||||||
"""Wait for a card and connect to it
|
"""Wait for a card and connect to it
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -98,7 +99,7 @@ class LinkBase(abc.ABC):
|
|||||||
"""Resets the card (power down/up)
|
"""Resets the card (power down/up)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def send_apdu_raw(self, pdu: str):
|
def send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
|
||||||
"""Sends an APDU with minimal processing
|
"""Sends an APDU with minimal processing
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -115,7 +116,7 @@ class LinkBase(abc.ABC):
|
|||||||
self.apdu_tracer.trace_response(pdu, sw, data)
|
self.apdu_tracer.trace_response(pdu, sw, data)
|
||||||
return (data, sw)
|
return (data, sw)
|
||||||
|
|
||||||
def send_apdu(self, pdu):
|
def send_apdu(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
|
||||||
"""Sends an APDU and auto fetch response data
|
"""Sends an APDU and auto fetch response data
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -144,7 +145,7 @@ class LinkBase(abc.ABC):
|
|||||||
|
|
||||||
return data, sw
|
return data, sw
|
||||||
|
|
||||||
def send_apdu_checksw(self, pdu, sw="9000"):
|
def send_apdu_checksw(self, pdu: Hexstr, sw: SwMatchstr = "9000") -> Tuple[Hexstr, SwHexstr]:
|
||||||
"""Sends an APDU and check returned SW
|
"""Sends an APDU and check returned SW
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -212,7 +213,8 @@ class LinkBase(abc.ABC):
|
|||||||
raise SwMatchError(rv[1], sw.lower(), self.sw_interpreter)
|
raise SwMatchError(rv[1], sw.lower(), self.sw_interpreter)
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def send_apdu_constr(self, cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr):
|
def send_apdu_constr(self, cla: Hexstr, ins: Hexstr, p1: Hexstr, p2: Hexstr, cmd_constr: Construct,
|
||||||
|
cmd_data: Hexstr, resp_constr: Construct) -> Tuple[dict, SwHexstr]:
|
||||||
"""Build and sends an APDU using a 'construct' definition; parses response.
|
"""Build and sends an APDU using a 'construct' definition; parses response.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -237,8 +239,9 @@ class LinkBase(abc.ABC):
|
|||||||
rsp = None
|
rsp = None
|
||||||
return (rsp, sw)
|
return (rsp, sw)
|
||||||
|
|
||||||
def send_apdu_constr_checksw(self, cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr,
|
def send_apdu_constr_checksw(self, cla: Hexstr, ins: Hexstr, p1: Hexstr, p2: Hexstr,
|
||||||
sw_exp="9000"):
|
cmd_constr: Construct, cmd_data: Hexstr, resp_constr: Construct,
|
||||||
|
sw_exp: SwMatchstr="9000") -> Tuple[dict, SwHexstr]:
|
||||||
"""Build and sends an APDU using a 'construct' definition; parses response.
|
"""Build and sends an APDU using a 'construct' definition; parses response.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@@ -21,9 +21,11 @@ import struct
|
|||||||
import socket
|
import socket
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
from pySim.transport import LinkBase
|
from pySim.transport import LinkBase
|
||||||
from pySim.exceptions import *
|
from pySim.exceptions import *
|
||||||
from pySim.utils import h2b, b2h
|
from pySim.utils import h2b, b2h, Hexstr, SwHexstr
|
||||||
|
|
||||||
|
|
||||||
class L1CTLMessage:
|
class L1CTLMessage:
|
||||||
@@ -91,7 +93,7 @@ class CalypsoSimLink(LinkBase):
|
|||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.sock.close()
|
self.sock.close()
|
||||||
|
|
||||||
def wait_for_rsp(self, exp_len=128):
|
def wait_for_rsp(self, exp_len: int = 128):
|
||||||
# Wait for incoming data (timeout is 3 seconds)
|
# Wait for incoming data (timeout is 3 seconds)
|
||||||
s, _, _ = select.select([self.sock], [], [], 3.0)
|
s, _, _ = select.select([self.sock], [], [], 3.0)
|
||||||
if not s:
|
if not s:
|
||||||
@@ -118,10 +120,10 @@ class CalypsoSimLink(LinkBase):
|
|||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
pass # Nothing to do really ...
|
pass # Nothing to do really ...
|
||||||
|
|
||||||
def wait_for_card(self, timeout=None, newcardonly=False):
|
def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False):
|
||||||
pass # Nothing to do really ...
|
pass # Nothing to do really ...
|
||||||
|
|
||||||
def _send_apdu_raw(self, pdu):
|
def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
|
||||||
|
|
||||||
# Request FULL reset
|
# Request FULL reset
|
||||||
req_msg = L1CTLMessageSIM(h2b(pdu))
|
req_msg = L1CTLMessageSIM(h2b(pdu))
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ import logging as log
|
|||||||
import serial
|
import serial
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
|
from pySim.utils import Hexstr, SwHexstr
|
||||||
from pySim.transport import LinkBase
|
from pySim.transport import LinkBase
|
||||||
from pySim.exceptions import *
|
from pySim.exceptions import *
|
||||||
|
|
||||||
@@ -136,10 +138,10 @@ class ModemATCommandLink(LinkBase):
|
|||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
pass # Nothing to do really ...
|
pass # Nothing to do really ...
|
||||||
|
|
||||||
def wait_for_card(self, timeout=None, newcardonly=False):
|
def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False):
|
||||||
pass # Nothing to do really ...
|
pass # Nothing to do really ...
|
||||||
|
|
||||||
def _send_apdu_raw(self, pdu):
|
def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
|
||||||
# Make sure pdu has upper case hex digits [A-F]
|
# Make sure pdu has upper case hex digits [A-F]
|
||||||
pdu = pdu.upper()
|
pdu = pdu.upper()
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
from smartcard.CardConnection import CardConnection
|
from smartcard.CardConnection import CardConnection
|
||||||
from smartcard.CardRequest import CardRequest
|
from smartcard.CardRequest import CardRequest
|
||||||
from smartcard.Exceptions import NoCardException, CardRequestTimeoutException, CardConnectionException, CardConnectionException
|
from smartcard.Exceptions import NoCardException, CardRequestTimeoutException, CardConnectionException, CardConnectionException
|
||||||
@@ -24,7 +26,7 @@ from smartcard.System import readers
|
|||||||
|
|
||||||
from pySim.exceptions import NoCardError, ProtocolError, ReaderError
|
from pySim.exceptions import NoCardError, ProtocolError, ReaderError
|
||||||
from pySim.transport import LinkBase
|
from pySim.transport import LinkBase
|
||||||
from pySim.utils import h2i, i2h
|
from pySim.utils import h2i, i2h, Hexstr, SwHexstr
|
||||||
|
|
||||||
|
|
||||||
class PcscSimLink(LinkBase):
|
class PcscSimLink(LinkBase):
|
||||||
@@ -46,7 +48,7 @@ class PcscSimLink(LinkBase):
|
|||||||
pass
|
pass
|
||||||
return
|
return
|
||||||
|
|
||||||
def wait_for_card(self, timeout: int = None, newcardonly: bool = False):
|
def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False):
|
||||||
cr = CardRequest(readers=[self._reader],
|
cr = CardRequest(readers=[self._reader],
|
||||||
timeout=timeout, newcardonly=newcardonly)
|
timeout=timeout, newcardonly=newcardonly)
|
||||||
try:
|
try:
|
||||||
@@ -68,7 +70,7 @@ class PcscSimLink(LinkBase):
|
|||||||
except NoCardException:
|
except NoCardException:
|
||||||
raise NoCardError()
|
raise NoCardError()
|
||||||
|
|
||||||
def get_atr(self):
|
def get_atr(self) -> Hexstr:
|
||||||
return self._con.getATR()
|
return self._con.getATR()
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
@@ -79,7 +81,7 @@ class PcscSimLink(LinkBase):
|
|||||||
self.connect()
|
self.connect()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def _send_apdu_raw(self, pdu):
|
def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
|
||||||
|
|
||||||
apdu = h2i(pdu)
|
apdu = h2i(pdu)
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,11 @@
|
|||||||
import serial
|
import serial
|
||||||
import time
|
import time
|
||||||
import os.path
|
import os.path
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
from pySim.exceptions import NoCardError, ProtocolError
|
from pySim.exceptions import NoCardError, ProtocolError
|
||||||
from pySim.transport import LinkBase
|
from pySim.transport import LinkBase
|
||||||
from pySim.utils import h2b, b2h
|
from pySim.utils import h2b, b2h, Hexstr, SwHexstr
|
||||||
|
|
||||||
|
|
||||||
class SerialSimLink(LinkBase):
|
class SerialSimLink(LinkBase):
|
||||||
@@ -51,7 +52,7 @@ class SerialSimLink(LinkBase):
|
|||||||
if (hasattr(self, "_sl")):
|
if (hasattr(self, "_sl")):
|
||||||
self._sl.close()
|
self._sl.close()
|
||||||
|
|
||||||
def wait_for_card(self, timeout=None, newcardonly=False):
|
def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False):
|
||||||
# Direct try
|
# Direct try
|
||||||
existing = False
|
existing = False
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ class SerialSimLink(LinkBase):
|
|||||||
def connect(self):
|
def connect(self):
|
||||||
self.reset_card()
|
self.reset_card()
|
||||||
|
|
||||||
def get_atr(self):
|
def get_atr(self) -> Hexstr:
|
||||||
return self._atr
|
return self._atr
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
@@ -184,7 +185,7 @@ class SerialSimLink(LinkBase):
|
|||||||
def _rx_byte(self):
|
def _rx_byte(self):
|
||||||
return self._sl.read()
|
return self._sl.read()
|
||||||
|
|
||||||
def _send_apdu_raw(self, pdu):
|
def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
|
||||||
|
|
||||||
pdu = h2b(pdu)
|
pdu = h2b(pdu)
|
||||||
data_len = pdu[4] # P3
|
data_len = pdu[4] # P3
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ from typing import Optional, List, Dict, Any, Tuple, NewType
|
|||||||
|
|
||||||
# just to differentiate strings of hex nibbles from everything else
|
# just to differentiate strings of hex nibbles from everything else
|
||||||
Hexstr = NewType('Hexstr', str)
|
Hexstr = NewType('Hexstr', str)
|
||||||
|
SwHexstr = NewType('SwHexstr', str)
|
||||||
|
SwMatchstr = NewType('SwMatchstr', str)
|
||||||
|
|
||||||
def h2b(s: Hexstr) -> bytearray:
|
def h2b(s: Hexstr) -> bytearray:
|
||||||
"""convert from a string of hex nibbles to a sequence of bytes"""
|
"""convert from a string of hex nibbles to a sequence of bytes"""
|
||||||
|
|||||||
Reference in New Issue
Block a user