Fix various mistakes around the CardADF <-> CardApplication dualism
When the CardFile hierarchy talks about 'application' it means CardADF.
When the RuntimeState and CardProfile talk about 'application' they mean
a CardApplication.
Let's clarify this in the file names, and make CardADF have an optional
reference to the CardApplication, so that application specific status
word interpretation really works.
Change-Id: Ibc80a41d79dca547f14d5d84f447742e6b46d7ca
diff --git a/pySim-shell.py b/pySim-shell.py
index 3c56f51..c170398 100755
--- a/pySim-shell.py
+++ b/pySim-shell.py
@@ -45,8 +45,8 @@
from pySim.filesystem import CardMF, RuntimeState, CardDF, CardADF
from pySim.ts_51_011 import CardProfileSIM, DF_TELECOM, DF_GSM
from pySim.ts_102_221 import CardProfileUICC
-from pySim.ts_31_102 import ADF_USIM
-from pySim.ts_31_103 import ADF_ISIM
+from pySim.ts_31_102 import CardApplicationUSIM
+from pySim.ts_31_103 import CardApplicationISIM
from pySim.card_data import CardDataCsv, card_data_register, card_data_get_field
@@ -441,8 +441,8 @@
sys.exit(2)
profile = CardProfileUICC()
- profile.add_application(ADF_USIM())
- profile.add_application(ADF_ISIM())
+ profile.add_application(CardApplicationUSIM)
+ profile.add_application(CardApplicationISIM)
rs = RuntimeState(card, profile)
diff --git a/pySim/filesystem.py b/pySim/filesystem.py
index be0aaf6..9a68d5a 100644
--- a/pySim/filesystem.py
+++ b/pySim/filesystem.py
@@ -284,8 +284,8 @@
def __str__(self):
return "MF(%s)" % (self.fid)
- def add_application(self, app:'CardADF'):
- """Add an ADF (Application Dedicated File) to the MF"""
+ def add_application_df(self, app:'CardADF'):
+ """Add an Application to the MF"""
if not isinstance(app, CardADF):
raise TypeError("Expected an ADF instance")
if app.aid in self.applications:
@@ -334,10 +334,12 @@
"""ADF (Application Dedicated File) in the smart card filesystem"""
def __init__(self, aid:str, **kwargs):
super().__init__(**kwargs)
+ # reference to CardApplication may be set from CardApplication constructor
+ self.application:Optional[CardApplication] = None
self.aid = aid # Application Identifier
mf = self.get_mf()
if mf:
- mf.add_application(self)
+ mf.add_application_df(self)
def __str__(self):
return "ADF(%s)" % (self.aid)
@@ -807,12 +809,13 @@
"""
self.mf = CardMF()
self.card = card
- self.selected_file = self.mf
+ self.selected_file:CardDF = self.mf
self.profile = profile
- # add applications + MF-files from profile
+ # add application ADFs + MF-files from profile
apps = self._match_applications()
for a in apps:
- self.mf.add_application(a)
+ if a.adf:
+ self.mf.add_application_df(a.adf)
for f in self.profile.files_in_mf:
self.mf.add_file(f)
self.conserve_write = True
@@ -849,8 +852,8 @@
else:
return self.selected_file.parent
- def get_application(self) -> Optional[CardADF]:
- """Obtain the currently selected application (if any).
+ def get_application_df(self) -> Optional[CardADF]:
+ """Obtain the currently selected application DF (if any).
Returns:
CardADF() instance or None"""
@@ -872,16 +875,16 @@
Returns:
Tuple of two strings
"""
- app = self.get_application()
- if app:
+ adf = self.get_application_df()
+ if adf:
+ app = adf.application
# The application either comes with its own interpret_sw
# method or we will use the interpret_sw method from the
# card profile.
- if hasattr(app, "interpret_sw"):
+ if app and hasattr(app, "interpret_sw"):
return app.interpret_sw(sw)
else:
return self.profile.interpret_sw(sw)
- return app.interpret_sw(sw)
else:
return self.profile.interpret_sw(sw)
@@ -1078,7 +1081,7 @@
class CardApplication(object):
"""A card application is represented by an ADF (with contained hierarchy) and optionally
some SW definitions."""
- def __init__(self, name, adf:str=None, sw:dict=None):
+ def __init__(self, name, adf:Optional[CardADF]=None, aid:str=None, sw:dict=None):
"""
Args:
adf : ADF name
@@ -1087,6 +1090,12 @@
self.name = name
self.adf = adf
self.sw = sw or dict()
+ # back-reference from ADF to Applicaiton
+ if self.adf:
+ self.aid = aid or self.adf.aid
+ self.adf.application = self
+ else:
+ self.aid = aid
def __str__(self):
return "APP(%s)" % (self.name)