pySim-shell: Move init_card() function to new pySim.app module
The point of this is to move generic code out of pySim-shell.py,
paving the way for more/other executables using the full power of
our class model without having to reinvent the wheel.
Change-Id: Icf557ed3064ef613ed693ce28bd3514a97a938bd
diff --git a/pySim-shell.py b/pySim-shell.py
index 0c559f9..795276a 100755
--- a/pySim-shell.py
+++ b/pySim-shell.py
@@ -2,7 +2,7 @@
# Interactive shell for working with SIM / UICC / USIM / ISIM cards
#
-# (C) 2021-2022 by Harald Welte <laforge@osmocom.org>
+# (C) 2021-2023 by Harald Welte <laforge@osmocom.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -48,111 +48,20 @@
from pprint import pprint as pp
from pySim.exceptions import *
-from pySim.commands import SimCardCommands
from pySim.transport import init_reader, ApduTracer, argparse_add_reader_args, ProactiveHandler
-from pySim.cards import card_detect, SimCardBase, UiccCardBase
from pySim.utils import h2b, b2h, i2h, swap_nibbles, rpad, JsonEncoder, bertlv_parse_one, sw_match
from pySim.utils import sanitize_pin_adm, tabulate_str_list, boxed_heading_str, Hexstr, dec_iccid
from pySim.utils import is_hexstr_or_decimal, is_hexstr, is_decimal
from pySim.card_handler import CardHandler, CardHandlerAuto
-from pySim.filesystem import CardDF, CardADF, CardModel, CardApplication
-from pySim.runtime import RuntimeState
-from pySim.profile import CardProfile
-from pySim.cdma_ruim import CardProfileRUIM
-from pySim.ts_102_221 import CardProfileUICC
+from pySim.filesystem import CardDF, CardADF
from pySim.ts_102_222 import Ts102222Commands
from pySim.gsm_r import DF_EIRENE
from pySim.cat import ProactiveCommand
-# we need to import this module so that the SysmocomSJA2 sub-class of
-# CardModel is created, which will add the ATR-based matching and
-# calling of SysmocomSJA2.add_files. See CardModel.apply_matching_models
-import pySim.sysmocom_sja2
-
-# we need to import these modules so that the various sub-classes of
-# CardProfile are created, which will be used in init_card() to iterate
-# over all known CardProfile sub-classes.
-import pySim.ts_31_102
-import pySim.ts_31_103
-import pySim.ts_31_104
-import pySim.ara_m
-import pySim.global_platform
-import pySim.euicc
-
from pySim.card_key_provider import CardKeyProviderCsv, card_key_provider_register, card_key_provider_get_field
-
-def init_card(sl):
- """
- Detect card in reader and setup card profile and runtime state. This
- function must be called at least once on startup. The card and runtime
- state object (rs) is required for all pySim-shell commands.
- """
-
- # Create command layer
- scc = SimCardCommands(transport=sl)
-
- # Wait up to three seconds for a card in reader and try to detect
- # the card type.
- print("Waiting for card...")
- try:
- sl.wait_for_card(3)
- except NoCardError:
- print("No card detected!")
- return None, None
- except:
- print("Card not readable!")
- return None, None
-
- generic_card = False
- card = card_detect(scc)
- if card is None:
- print("Warning: Could not detect card type - assuming a generic card type...")
- card = SimCardBase(scc)
- generic_card = True
-
- profile = CardProfile.pick(scc)
- if profile is None:
- print("Unsupported card type!")
- return None, card
-
- # ETSI TS 102 221, Table 9.3 specifies a default for the PIN key
- # references, however card manufactures may still decide to pick an
- # arbitrary key reference. In case we run on a generic card class that is
- # detected as an UICC, we will pick the key reference that is officially
- # specified.
- if generic_card and isinstance(profile, CardProfileUICC):
- card._adm_chv_num = 0x0A
-
- print("Info: Card is of type: %s" % str(profile))
-
- # FIXME: this shouldn't really be here but somewhere else/more generic.
- # We cannot do it within pySim/profile.py as that would create circular
- # dependencies between the individual profiles and profile.py.
- if isinstance(profile, CardProfileUICC):
- for app_cls in CardApplication.__subclasses__():
- constr_sig = inspect.signature(app_cls.__init__)
- # skip any intermediary sub-classes such as CardApplicationSD
- if len(constr_sig.parameters) != 1:
- continue
- profile.add_application(app_cls())
- # We have chosen SimCard() above, but we now know it actually is an UICC
- # so it's safe to assume it supports USIM application (which we're adding above).
- # IF we don't do this, we will have a SimCard but try USIM specific commands like
- # the update_ust method (see https://osmocom.org/issues/6055)
- if generic_card:
- card = UiccCardBase(scc)
-
- # Create runtime state with card profile
- rs = RuntimeState(card, profile)
-
- CardModel.apply_matching_models(scc, rs)
-
- # inform the transport that we can do context-specific SW interpretation
- sl.set_sw_interpreter(rs)
-
- return rs, card
+from pySim.app import init_card
class Cmd2Compat(cmd2.Cmd):