mirror of https://gerrit.osmocom.org/pysim
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
This commit is contained in:
parent
1e45657e0f
commit
5ce3524f5f
|
@ -45,8 +45,8 @@ from pySim.card_handler import card_handler
|
||||||
from pySim.filesystem import CardMF, RuntimeState, CardDF, CardADF
|
from pySim.filesystem import CardMF, RuntimeState, CardDF, CardADF
|
||||||
from pySim.ts_51_011 import CardProfileSIM, DF_TELECOM, DF_GSM
|
from pySim.ts_51_011 import CardProfileSIM, DF_TELECOM, DF_GSM
|
||||||
from pySim.ts_102_221 import CardProfileUICC
|
from pySim.ts_102_221 import CardProfileUICC
|
||||||
from pySim.ts_31_102 import ADF_USIM
|
from pySim.ts_31_102 import CardApplicationUSIM
|
||||||
from pySim.ts_31_103 import ADF_ISIM
|
from pySim.ts_31_103 import CardApplicationISIM
|
||||||
|
|
||||||
from pySim.card_data import CardDataCsv, card_data_register, card_data_get_field
|
from pySim.card_data import CardDataCsv, card_data_register, card_data_get_field
|
||||||
|
|
||||||
|
@ -441,8 +441,8 @@ if __name__ == '__main__':
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
profile = CardProfileUICC()
|
profile = CardProfileUICC()
|
||||||
profile.add_application(ADF_USIM())
|
profile.add_application(CardApplicationUSIM)
|
||||||
profile.add_application(ADF_ISIM())
|
profile.add_application(CardApplicationISIM)
|
||||||
|
|
||||||
rs = RuntimeState(card, profile)
|
rs = RuntimeState(card, profile)
|
||||||
|
|
||||||
|
|
|
@ -284,8 +284,8 @@ class CardMF(CardDF):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "MF(%s)" % (self.fid)
|
return "MF(%s)" % (self.fid)
|
||||||
|
|
||||||
def add_application(self, app:'CardADF'):
|
def add_application_df(self, app:'CardADF'):
|
||||||
"""Add an ADF (Application Dedicated File) to the MF"""
|
"""Add an Application to the MF"""
|
||||||
if not isinstance(app, CardADF):
|
if not isinstance(app, CardADF):
|
||||||
raise TypeError("Expected an ADF instance")
|
raise TypeError("Expected an ADF instance")
|
||||||
if app.aid in self.applications:
|
if app.aid in self.applications:
|
||||||
|
@ -334,10 +334,12 @@ class CardADF(CardDF):
|
||||||
"""ADF (Application Dedicated File) in the smart card filesystem"""
|
"""ADF (Application Dedicated File) in the smart card filesystem"""
|
||||||
def __init__(self, aid:str, **kwargs):
|
def __init__(self, aid:str, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
# reference to CardApplication may be set from CardApplication constructor
|
||||||
|
self.application:Optional[CardApplication] = None
|
||||||
self.aid = aid # Application Identifier
|
self.aid = aid # Application Identifier
|
||||||
mf = self.get_mf()
|
mf = self.get_mf()
|
||||||
if mf:
|
if mf:
|
||||||
mf.add_application(self)
|
mf.add_application_df(self)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "ADF(%s)" % (self.aid)
|
return "ADF(%s)" % (self.aid)
|
||||||
|
@ -807,12 +809,13 @@ class RuntimeState(object):
|
||||||
"""
|
"""
|
||||||
self.mf = CardMF()
|
self.mf = CardMF()
|
||||||
self.card = card
|
self.card = card
|
||||||
self.selected_file = self.mf
|
self.selected_file:CardDF = self.mf
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
# add applications + MF-files from profile
|
# add application ADFs + MF-files from profile
|
||||||
apps = self._match_applications()
|
apps = self._match_applications()
|
||||||
for a in apps:
|
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:
|
for f in self.profile.files_in_mf:
|
||||||
self.mf.add_file(f)
|
self.mf.add_file(f)
|
||||||
self.conserve_write = True
|
self.conserve_write = True
|
||||||
|
@ -849,8 +852,8 @@ class RuntimeState(object):
|
||||||
else:
|
else:
|
||||||
return self.selected_file.parent
|
return self.selected_file.parent
|
||||||
|
|
||||||
def get_application(self) -> Optional[CardADF]:
|
def get_application_df(self) -> Optional[CardADF]:
|
||||||
"""Obtain the currently selected application (if any).
|
"""Obtain the currently selected application DF (if any).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
CardADF() instance or None"""
|
CardADF() instance or None"""
|
||||||
|
@ -872,16 +875,16 @@ class RuntimeState(object):
|
||||||
Returns:
|
Returns:
|
||||||
Tuple of two strings
|
Tuple of two strings
|
||||||
"""
|
"""
|
||||||
app = self.get_application()
|
adf = self.get_application_df()
|
||||||
if app:
|
if adf:
|
||||||
|
app = adf.application
|
||||||
# The application either comes with its own interpret_sw
|
# The application either comes with its own interpret_sw
|
||||||
# method or we will use the interpret_sw method from the
|
# method or we will use the interpret_sw method from the
|
||||||
# card profile.
|
# card profile.
|
||||||
if hasattr(app, "interpret_sw"):
|
if app and hasattr(app, "interpret_sw"):
|
||||||
return app.interpret_sw(sw)
|
return app.interpret_sw(sw)
|
||||||
else:
|
else:
|
||||||
return self.profile.interpret_sw(sw)
|
return self.profile.interpret_sw(sw)
|
||||||
return app.interpret_sw(sw)
|
|
||||||
else:
|
else:
|
||||||
return self.profile.interpret_sw(sw)
|
return self.profile.interpret_sw(sw)
|
||||||
|
|
||||||
|
@ -1078,7 +1081,7 @@ def interpret_sw(sw_data:dict, sw:str):
|
||||||
class CardApplication(object):
|
class CardApplication(object):
|
||||||
"""A card application is represented by an ADF (with contained hierarchy) and optionally
|
"""A card application is represented by an ADF (with contained hierarchy) and optionally
|
||||||
some SW definitions."""
|
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:
|
Args:
|
||||||
adf : ADF name
|
adf : ADF name
|
||||||
|
@ -1087,6 +1090,12 @@ class CardApplication(object):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.adf = adf
|
self.adf = adf
|
||||||
self.sw = sw or dict()
|
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):
|
def __str__(self):
|
||||||
return "APP(%s)" % (self.name)
|
return "APP(%s)" % (self.name)
|
||||||
|
|
Loading…
Reference in New Issue