pySim/transport: More type annotations

Change-Id: I62e081271e3a579851a588a4ed7282017e56f852
diff --git a/pySim/transport/__init__.py b/pySim/transport/__init__.py
index 09752ac..a16fdb3 100644
--- a/pySim/transport/__init__.py
+++ b/pySim/transport/__init__.py
@@ -6,10 +6,11 @@
 import abc
 import argparse
 from typing import Optional, Tuple
+from construct import Construct
 
 from pySim.exceptions import *
 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
 
 #
@@ -60,14 +61,14 @@
 class LinkBase(abc.ABC):
     """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):
         self.sw_interpreter = sw_interpreter
         self.apdu_tracer = apdu_tracer
         self.proactive_handler = proactive_handler
 
     @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."""
 
     def set_sw_interpreter(self, interp):
@@ -75,7 +76,7 @@
         self.sw_interpreter = interp
 
     @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
 
         Args:
@@ -98,7 +99,7 @@
         """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
 
         Args:
@@ -115,7 +116,7 @@
             self.apdu_tracer.trace_response(pdu, sw, data)
         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
 
         Args:
@@ -144,7 +145,7 @@
 
         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
 
         Args:
@@ -212,7 +213,8 @@
             raise SwMatchError(rv[1], sw.lower(), self.sw_interpreter)
         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.
 
         Args:
@@ -237,8 +239,9 @@
             rsp = None
         return (rsp, sw)
 
-    def send_apdu_constr_checksw(self, cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr,
-                                 sw_exp="9000"):
+    def send_apdu_constr_checksw(self, cla: Hexstr, ins: Hexstr, p1: Hexstr, p2: Hexstr,
+                                 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.
 
         Args:
diff --git a/pySim/transport/calypso.py b/pySim/transport/calypso.py
index e1326ac..4244b23 100644
--- a/pySim/transport/calypso.py
+++ b/pySim/transport/calypso.py
@@ -21,9 +21,11 @@
 import socket
 import os
 
+from typing import Optional, Tuple
+
 from pySim.transport import LinkBase
 from pySim.exceptions import *
-from pySim.utils import h2b, b2h
+from pySim.utils import h2b, b2h, Hexstr, SwHexstr
 
 
 class L1CTLMessage:
@@ -91,7 +93,7 @@
     def __del__(self):
         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)
         s, _, _ = select.select([self.sock], [], [], 3.0)
         if not s:
@@ -118,10 +120,10 @@
     def disconnect(self):
         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 ...
 
-    def _send_apdu_raw(self, pdu):
+    def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
 
         # Request FULL reset
         req_msg = L1CTLMessageSIM(h2b(pdu))
diff --git a/pySim/transport/modem_atcmd.py b/pySim/transport/modem_atcmd.py
index ea50bc9..c6f6c57 100644
--- a/pySim/transport/modem_atcmd.py
+++ b/pySim/transport/modem_atcmd.py
@@ -20,7 +20,9 @@
 import serial
 import time
 import re
+from typing import Optional, Tuple
 
+from pySim.utils import Hexstr, SwHexstr
 from pySim.transport import LinkBase
 from pySim.exceptions import *
 
@@ -136,10 +138,10 @@
     def disconnect(self):
         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 ...
 
-    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]
         pdu = pdu.upper()
 
diff --git a/pySim/transport/pcsc.py b/pySim/transport/pcsc.py
index e3f2546..f0b3e67 100644
--- a/pySim/transport/pcsc.py
+++ b/pySim/transport/pcsc.py
@@ -17,6 +17,8 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+from typing import Optional, Tuple
+
 from smartcard.CardConnection import CardConnection
 from smartcard.CardRequest import CardRequest
 from smartcard.Exceptions import NoCardException, CardRequestTimeoutException, CardConnectionException, CardConnectionException
@@ -24,7 +26,7 @@
 
 from pySim.exceptions import NoCardError, ProtocolError, ReaderError
 from pySim.transport import LinkBase
-from pySim.utils import h2i, i2h
+from pySim.utils import h2i, i2h, Hexstr, SwHexstr
 
 
 class PcscSimLink(LinkBase):
@@ -46,7 +48,7 @@
             pass
         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],
                          timeout=timeout, newcardonly=newcardonly)
         try:
@@ -68,7 +70,7 @@
         except NoCardException:
             raise NoCardError()
 
-    def get_atr(self):
+    def get_atr(self) -> Hexstr:
         return self._con.getATR()
 
     def disconnect(self):
@@ -79,7 +81,7 @@
         self.connect()
         return 1
 
-    def _send_apdu_raw(self, pdu):
+    def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
 
         apdu = h2i(pdu)
 
diff --git a/pySim/transport/serial.py b/pySim/transport/serial.py
index 3313a5e..daf2eb8 100644
--- a/pySim/transport/serial.py
+++ b/pySim/transport/serial.py
@@ -19,10 +19,11 @@
 import serial
 import time
 import os.path
+from typing import Optional, Tuple
 
 from pySim.exceptions import NoCardError, ProtocolError
 from pySim.transport import LinkBase
-from pySim.utils import h2b, b2h
+from pySim.utils import h2b, b2h, Hexstr, SwHexstr
 
 
 class SerialSimLink(LinkBase):
@@ -51,7 +52,7 @@
         if (hasattr(self, "_sl")):
             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
         existing = False
 
@@ -92,7 +93,7 @@
     def connect(self):
         self.reset_card()
 
-    def get_atr(self):
+    def get_atr(self) -> Hexstr:
         return self._atr
 
     def disconnect(self):
@@ -184,7 +185,7 @@
     def _rx_byte(self):
         return self._sl.read()
 
-    def _send_apdu_raw(self, pdu):
+    def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]:
 
         pdu = h2b(pdu)
         data_len = pdu[4]  # P3
diff --git a/pySim/utils.py b/pySim/utils.py
index b534580..22dcda3 100644
--- a/pySim/utils.py
+++ b/pySim/utils.py
@@ -28,7 +28,8 @@
 
 # just to differentiate strings of hex nibbles from everything else
 Hexstr = NewType('Hexstr', str)
-
+SwHexstr = NewType('SwHexstr', str)
+SwMatchstr = NewType('SwMatchstr', str)
 
 def h2b(s: Hexstr) -> bytearray:
     """convert from a string of hex nibbles to a sequence of bytes"""