forked from public/pysim
pySim/cards: Add type annotations
Change-Id: Id5752a64b59097584301c860ebf74d858ed3d240
This commit is contained in:
@@ -25,29 +25,31 @@
|
|||||||
from typing import Optional, Dict, Tuple
|
from typing import Optional, Dict, Tuple
|
||||||
from pySim.ts_102_221 import EF_DIR, EF_ICCID
|
from pySim.ts_102_221 import EF_DIR, EF_ICCID
|
||||||
from pySim.ts_51_011 import DF_GSM
|
from pySim.ts_51_011 import DF_GSM
|
||||||
|
from pySim.transport import LinkBase
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
from pySim.utils import *
|
from pySim.utils import *
|
||||||
|
from pySim.commands import Path
|
||||||
|
|
||||||
class CardBase:
|
class CardBase:
|
||||||
"""General base class for some kind of telecommunications card."""
|
"""General base class for some kind of telecommunications card."""
|
||||||
def __init__(self, scc):
|
def __init__(self, scc: LinkBase):
|
||||||
self._scc = scc
|
self._scc = scc
|
||||||
self._aids = []
|
self._aids = []
|
||||||
|
|
||||||
def reset(self):
|
def reset(self) -> Optional[Hexstr]:
|
||||||
rc = self._scc.reset_card()
|
rc = self._scc.reset_card()
|
||||||
if rc == 1:
|
if rc == 1:
|
||||||
return self._scc.get_atr()
|
return self._scc.get_atr()
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_apdu_parameter(self, cla, sel_ctrl):
|
def set_apdu_parameter(self, cla: Hexstr, sel_ctrl: Hexstr) -> None:
|
||||||
"""Set apdu parameters (class byte and selection control bytes)"""
|
"""Set apdu parameters (class byte and selection control bytes)"""
|
||||||
self._scc.cla_byte = cla
|
self._scc.cla_byte = cla
|
||||||
self._scc.sel_ctrl = sel_ctrl
|
self._scc.sel_ctrl = sel_ctrl
|
||||||
|
|
||||||
def get_apdu_parameter(self):
|
def get_apdu_parameter(self) -> Tuple[Hexstr, Hexstr]:
|
||||||
"""Get apdu parameters (class byte and selection control bytes)"""
|
"""Get apdu parameters (class byte and selection control bytes)"""
|
||||||
return (self._scc.cla_byte, self._scc.sel_ctrl)
|
return (self._scc.cla_byte, self._scc.sel_ctrl)
|
||||||
|
|
||||||
@@ -55,19 +57,19 @@ class CardBase:
|
|||||||
print("warning: erasing is not supported for specified card type!")
|
print("warning: erasing is not supported for specified card type!")
|
||||||
return
|
return
|
||||||
|
|
||||||
def file_exists(self, fid):
|
def file_exists(self, fid: Path) -> bool:
|
||||||
res_arr = self._scc.try_select_path(fid)
|
res_arr = self._scc.try_select_path(fid)
|
||||||
for res in res_arr:
|
for res in res_arr:
|
||||||
if res[1] != '9000':
|
if res[1] != '9000':
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def read_aids(self):
|
def read_aids(self) -> List[Hexstr]:
|
||||||
# a non-UICC doesn't have any applications. Convenience helper to avoid
|
# a non-UICC doesn't have any applications. Convenience helper to avoid
|
||||||
# callers having to do hasattr('read_aids') ahead of every call.
|
# callers having to do hasattr('read_aids') ahead of every call.
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def read_iccid(self):
|
def read_iccid(self) -> Tuple[Optional[Hexstr], SwHexstr]:
|
||||||
ef_iccid = EF_ICCID()
|
ef_iccid = EF_ICCID()
|
||||||
(res, sw) = self._scc.read_binary(ef_iccid.fid)
|
(res, sw) = self._scc.read_binary(ef_iccid.fid)
|
||||||
if sw == '9000':
|
if sw == '9000':
|
||||||
@@ -81,7 +83,7 @@ class SimCardBase(CardBase):
|
|||||||
any higher-layer processing."""
|
any higher-layer processing."""
|
||||||
name = 'SIM'
|
name = 'SIM'
|
||||||
|
|
||||||
def probe(self):
|
def probe(self) -> bool:
|
||||||
df_gsm = DF_GSM()
|
df_gsm = DF_GSM()
|
||||||
return self.file_exists(df_gsm.fid)
|
return self.file_exists(df_gsm.fid)
|
||||||
|
|
||||||
@@ -89,17 +91,17 @@ class SimCardBase(CardBase):
|
|||||||
class UiccCardBase(SimCardBase):
|
class UiccCardBase(SimCardBase):
|
||||||
name = 'UICC'
|
name = 'UICC'
|
||||||
|
|
||||||
def __init__(self, ssc):
|
def __init__(self, ssc: LinkBase):
|
||||||
super(UiccCardBase, self).__init__(ssc)
|
super(UiccCardBase, self).__init__(ssc)
|
||||||
# See also: ETSI TS 102 221, Table 9.3
|
# See also: ETSI TS 102 221, Table 9.3
|
||||||
self._adm_chv_num = 0xA0
|
self._adm_chv_num = 0xA0
|
||||||
|
|
||||||
def probe(self):
|
def probe(self) -> bool:
|
||||||
# EF.DIR is a mandatory EF on all ICCIDs; however it *may* also exist on a TS 51.011 SIM
|
# EF.DIR is a mandatory EF on all ICCIDs; however it *may* also exist on a TS 51.011 SIM
|
||||||
ef_dir = EF_DIR()
|
ef_dir = EF_DIR()
|
||||||
return self.file_exists(ef_dir.fid)
|
return self.file_exists(ef_dir.fid)
|
||||||
|
|
||||||
def read_aids(self):
|
def read_aids(self) -> List[Hexstr]:
|
||||||
"""Fetch all the AIDs present on UICC"""
|
"""Fetch all the AIDs present on UICC"""
|
||||||
self._aids = []
|
self._aids = []
|
||||||
try:
|
try:
|
||||||
@@ -118,7 +120,7 @@ class UiccCardBase(SimCardBase):
|
|||||||
return self._aids
|
return self._aids
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_aid(adf="usim") -> str:
|
def _get_aid(adf="usim") -> Optional[Hexstr]:
|
||||||
aid_map = {}
|
aid_map = {}
|
||||||
# First (known) halves of the U/ISIM AID
|
# First (known) halves of the U/ISIM AID
|
||||||
aid_map["usim"] = "a0000000871002"
|
aid_map["usim"] = "a0000000871002"
|
||||||
@@ -128,7 +130,7 @@ class UiccCardBase(SimCardBase):
|
|||||||
return aid_map[adf]
|
return aid_map[adf]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _complete_aid(self, aid) -> str:
|
def _complete_aid(self, aid: Hexstr) -> Optional[Hexstr]:
|
||||||
"""find the complete version of an ADF.U/ISIM AID"""
|
"""find the complete version of an ADF.U/ISIM AID"""
|
||||||
# Find full AID by partial AID:
|
# Find full AID by partial AID:
|
||||||
if is_hex(aid):
|
if is_hex(aid):
|
||||||
@@ -137,7 +139,7 @@ class UiccCardBase(SimCardBase):
|
|||||||
return aid_known
|
return aid_known
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def adf_present(self, adf="usim") -> bool:
|
def adf_present(self, adf: str = "usim") -> bool:
|
||||||
"""Check if the AID of the specified ADF is present in EF.DIR (call read_aids before use)"""
|
"""Check if the AID of the specified ADF is present in EF.DIR (call read_aids before use)"""
|
||||||
aid = self._get_aid(adf)
|
aid = self._get_aid(adf)
|
||||||
if aid:
|
if aid:
|
||||||
@@ -146,7 +148,7 @@ class UiccCardBase(SimCardBase):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def select_adf_by_aid(self, adf="usim"):
|
def select_adf_by_aid(self, adf: str = "usim") -> Tuple[Optional[Hexstr], Optional[SwHexstr]]:
|
||||||
"""Select ADF.U/ISIM in the Card using its full AID"""
|
"""Select ADF.U/ISIM in the Card using its full AID"""
|
||||||
if is_hex(adf):
|
if is_hex(adf):
|
||||||
aid = adf
|
aid = adf
|
||||||
@@ -161,7 +163,7 @@ class UiccCardBase(SimCardBase):
|
|||||||
return self._scc.select_adf(aid)
|
return self._scc.select_adf(aid)
|
||||||
return (None, None)
|
return (None, None)
|
||||||
|
|
||||||
def card_detect(scc):
|
def card_detect(scc: LinkBase) -> Optional[CardBase]:
|
||||||
# UICC always has higher preference, as a UICC might also contain a SIM application
|
# UICC always has higher preference, as a UICC might also contain a SIM application
|
||||||
uicc = UiccCardBase(scc)
|
uicc = UiccCardBase(scc)
|
||||||
if uicc.probe():
|
if uicc.probe():
|
||||||
|
|||||||
Reference in New Issue
Block a user