laforge has uploaded this change for review. (
https://gerrit.osmocom.org/c/pysim/+/38175?usp=email )
Change subject: pySim.profile: Further refactor card <-> profile matching
......................................................................
pySim.profile: Further refactor card <-> profile matching
The new architecture avoids sim/ruim/uicc specific methods in
pySim.profile and instead moves the profile-specific code into the
profile; it also solves everything within the class hierarchy, no need
for global methods.
Change-Id: I3b6c44d2f5cce2513c3ec8a3ce939a242f3e4901
---
M pySim/cdma_ruim.py
M pySim/profile.py
M pySim/ts_102_221.py
M pySim/ts_51_011.py
4 files changed, 55 insertions(+), 56 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/75/38175/1
diff --git a/pySim/cdma_ruim.py b/pySim/cdma_ruim.py
index 747a0d2..f5382c9 100644
--- a/pySim/cdma_ruim.py
+++ b/pySim/cdma_ruim.py
@@ -24,7 +24,6 @@
from osmocom.construct import *
from pySim.filesystem import *
-from pySim.profile import match_ruim
from pySim.profile import CardProfile, CardProfileAddon
from pySim.ts_51_011 import CardProfileSIM
from pySim.ts_51_011 import DF_TELECOM, DF_GSM
@@ -191,8 +190,11 @@
return CardProfileSIM.decode_select_response(data_hex)
@classmethod
- def match_with_card(cls, scc: SimCardCommands) -> bool:
- return match_ruim(scc)
+ def _try_match_card(cls, scc: SimCardCommands) -> None:
+ """ Try to access MF/DF.CDMA via 2G APDUs (3GPP TS 11.11), if this
works,
+ the card is considered an R-UIM card for CDMA."""
+ cls._mf_select_test(scc, "a0", "0000", ["3f00",
"7f25"])
+
class AddonRUIM(CardProfileAddon):
"""An Addon that can be found on on a combined SIM + RUIM or UICC +
RUIM to support CDMA."""
diff --git a/pySim/profile.py b/pySim/profile.py
index ae9e19f..e1fd11f 100644
--- a/pySim/profile.py
+++ b/pySim/profile.py
@@ -25,54 +25,11 @@
import operator
from typing import List
+from pySim.exceptions import SwMatchError
from pySim.commands import SimCardCommands
from pySim.filesystem import CardApplication, interpret_sw
from pySim.utils import all_subclasses
-def _mf_select_test(scc: SimCardCommands,
- cla_byte: str, sel_ctrl: str,
- fids: List[str]) -> bool:
- cla_byte_bak = scc.cla_byte
- sel_ctrl_bak = scc.sel_ctrl
- scc.reset_card()
-
- scc.cla_byte = cla_byte
- scc.sel_ctrl = sel_ctrl
- rc = True
- try:
- for fid in fids:
- scc.select_file(fid)
- except:
- rc = False
-
- scc.reset_card()
- scc.cla_byte = cla_byte_bak
- scc.sel_ctrl = sel_ctrl_bak
- return rc
-
-
-def match_uicc(scc: SimCardCommands) -> bool:
- """ Try to access MF via UICC APDUs (3GPP TS 102.221), if this works,
the
- card is considered a UICC card.
- """
- return _mf_select_test(scc, "00", "0004", ["3f00"])
-
-
-def match_sim(scc: SimCardCommands) -> bool:
- """ Try to access MF via 2G APDUs (3GPP TS 11.11), if this works, the
card
- is also a simcard. This will be the case for most UICC cards, but there may
- also be plain UICC cards without 2G support as well.
- """
- return _mf_select_test(scc, "a0", "0000", ["3f00"])
-
-
-def match_ruim(scc: SimCardCommands) -> bool:
- """ Try to access MF/DF.CDMA via 2G APDUs (3GPP TS 11.11), if this
works,
- the card is considered an R-UIM card for CDMA.
- """
- return _mf_select_test(scc, "a0", "0000", ["3f00",
"7f25"])
-
-
class CardProfile:
"""A Card Profile describes a card, it's filesystem hierarchy, an
[initial] list of
applications as well as profile-specific SW and shell commands. Every card has
@@ -137,14 +94,54 @@
"""
return data_hex
+ @staticmethod
+ def _mf_select_test(scc: SimCardCommands,
+ cla_byte: str, sel_ctrl: str,
+ fids: List[str]) -> bool:
+ """Helper function used by some derived _try_match_card()
methods."""
+ scc.reset_card()
+
+ scc.cla_byte = cla_byte
+ scc.sel_ctrl = sel_ctrl
+ for fid in fids:
+ scc.select_file(fid)
+
+ @staticmethod
+ def _match_helper(scc, fn) -> bool:
+ sel_backup = scc.sel_ctrl
+ cla_backup = scc.cla_byte
+ try:
+ fn(scc)
+ return True
+ except SwMatchError:
+ return False
+ finally:
+ scc.sel_ctrl = sel_backup
+ scc.cla_byte = cla_backup
+ scc.reset_card()
+
@classmethod
@abc.abstractmethod
- def match_with_card(cls, scc: SimCardCommands) -> bool:
- """Check if the specific profile matches the card. This method is
a
+ def _try_match_card(cls, scc: SimCardCommands) -> None:
+ """Try to see if the specific profile matches the card. This
method is a
placeholder that is overloaded by specific dirived classes. The method
actively probes the card to make sure the profile class matches the
physical card. This usually also means that the card is reset during
the process, so this method must not be called at random times. It may
+ only be called on startup. If there is no exception raised, we assume
+ the card matches the profile.
+
+ Args:
+ scc: SimCardCommands class
+ """
+ pass
+
+ @classmethod
+ def match_with_card(cls, scc: SimCardCommands) -> bool:
+ """Check if the specific profile matches the card. The method
+ actively probes the card to make sure the profile class matches the
+ physical card. This usually also means that the card is reset during
+ the process, so this method must not be called at random times. It may
only be called on startup.
Args:
@@ -152,7 +149,7 @@
Returns:
match = True, no match = False
"""
- return False
+ return cls._match_helper(scc, cls._try_match_card)
@staticmethod
def pick(scc: SimCardCommands):
diff --git a/pySim/ts_102_221.py b/pySim/ts_102_221.py
index c1c1388..9fed6af 100644
--- a/pySim/ts_102_221.py
+++ b/pySim/ts_102_221.py
@@ -27,7 +27,6 @@
from pySim.utils import *
from pySim.filesystem import *
from pySim.profile import CardProfile
-from pySim.profile import match_uicc
from pySim import iso7816_4
# A UICC will usually also support 2G functionality. If this is the case, we
@@ -885,8 +884,10 @@
return flatten_dict_lists(d['fcp_template'])
@classmethod
- def match_with_card(cls, scc: SimCardCommands) -> bool:
- return match_uicc(scc)
+ def _try_match_card(cls, scc: SimCardCommands) -> None:
+ """ Try to access MF via UICC APDUs (3GPP TS 102.221), if this
works, the
+ card is considered a UICC card."""
+ cls._mf_select_test(scc, "00", "0004", ["3f00"])
@with_default_category('TS 102 221 Specific Commands')
class AddlShellCommands(CommandSet):
diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py
index 69c8c79..8cbca58 100644
--- a/pySim/ts_51_011.py
+++ b/pySim/ts_51_011.py
@@ -41,7 +41,6 @@
from pySim.utils import dec_iccid, enc_iccid, dec_imsi, enc_imsi, dec_plmn, enc_plmn,
dec_xplmn_w_act
from pySim.utils import dec_msisdn, enc_msisdn
-from pySim.profile import match_sim
from pySim.profile import CardProfile, CardProfileAddon
from pySim.filesystem import *
from pySim.ts_31_102_telecom import DF_PHONEBOOK, DF_MULTIMEDIA, DF_MCS, DF_V2X
@@ -1193,8 +1192,8 @@
return ret
@classmethod
- def match_with_card(cls, scc: SimCardCommands) -> bool:
- return match_sim(scc)
+ def _try_match_card(cls, scc: SimCardCommands) -> None:
+ cls._mf_select_test(scc, "a0", "0000", ["3f00"])
class AddonSIM(CardProfileAddon):
--
To view, visit
https://gerrit.osmocom.org/c/pysim/+/38175?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I3b6c44d2f5cce2513c3ec8a3ce939a242f3e4901
Gerrit-Change-Number: 38175
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>