laforge has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/pysim/+/37619?usp=email )


Change subject: pySim.esim.saip: Decode each 'File' element in ProfileElement
......................................................................

pySim.esim.saip: Decode each 'File' element in ProfileElement

When loading a ProfileElement from its DER-ecoded format, populate
a dict with a pySim.esim.saip.File object for each file.

Change-Id: Ie2791c10289eb28daed2904467b0c5e5b11c94c2
---
M pySim/esim/saip/__init__.py
1 file changed, 59 insertions(+), 16 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/19/37619/1

diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py
index abaa679..c76cb5c 100644
--- a/pySim/esim/saip/__init__.py
+++ b/pySim/esim/saip/__init__.py
@@ -147,9 +147,10 @@
                 if k == 'fileDescriptor':
                     return v
         fd = get_fileDescriptor(l)
-        if not fd:
-            raise ValueError("No fileDescriptor found")
-        self.fileDescriptor.update(dict(fd))
+        if not fd and not self.fileDescriptor:
+            raise ValueError("No fileDescriptor found in tuple, and none set 
by template before")
+        if fd:
+            self.fileDescriptor.update(dict(fd))
         self.stream = self.linearize_file_content(l)

     def to_tuples(self) -> List[Tuple]:
@@ -262,13 +263,6 @@
         """Return the decoded templateID used by this profile element (if 
any)."""
         return self.decoded.get('templateID', None)

-    @property
-    def files(self):
-        """Return dict of decoded 'File' ASN.1 items."""
-        if not self.type in self.FILE_BEARING:
-            return {}
-        return {k:v for (k,v) in self.decoded.items() if k not in 
['templateID', self.header_name]}
-
     @classmethod
     def from_der(cls, der: bytes) -> 'ProfileElement':
         class4petype = {
@@ -311,7 +305,44 @@
     def __str__(self) -> str:
         return self.type

-class ProfileElementMF(ProfileElement):
+class FsProfileElement(ProfileElement):
+    """A file-system bearing profile element, like MF, USIM, ...."""
+
+    def __init__(self, decoded = None, mandated: bool = True):
+        super().__init__(decoded, mandated)
+        # indexed by PE-Name
+        self.files = {}
+        self.tdef = asn1.types['ProfileElement'].type.name_to_member[self.type]
+
+    def add_file(self, file: File):
+        """Add a File to the ProfileElement."""
+        if file.pe_name in self.files:
+            raise KeyError('Cannot add file: %s already exists' % file.pename)
+        self.files[file.pe_name] = file
+
+    def files2pe(self):
+        """Update the "decoded" member with the contents of the files 
member."""
+        for f in self.files:
+            self.decoded[f.pename] = f.to_tuples()
+
+    def pe2files(self):
+        """Update the "files" member with the contents of the "decoded" 
member."""
+        tdict = {x.name: x for x in self.tdef.root_members}
+        template = 
templates.ProfileTemplateRegistry.get_by_oid(self.templateID)
+        for k, v in self.decoded.items():
+            if tdict[k].type_name == 'File':
+                self.add_file(File(k, v, template.files_by_pename.get(k, 
None)))
+
+    def _post_decode(self):
+        # not entirely sure about this automatism
+        self.pe2files()
+
+    def _pre_encode(self):
+        # should we do self.pe2files()?  I don't think so
+        #self.files2pe()
+        pass
+
+class ProfileElementMF(FsProfileElement):
     type = 'mf'

     def __init__(self, decoded: Optional[dict] = None):
@@ -390,7 +421,7 @@
         self.decoded['pinCodes'][1].append(pin)


-class ProfileElementTelecom(ProfileElement):
+class ProfileElementTelecom(FsProfileElement):
     type = 'telecom'

     def __init__(self, decoded: Optional[dict] = None):
@@ -576,7 +607,7 @@
                     'adfAdminAccessDomain': ADM1_ACCESS,
                 }

-class ProfileElementUSIM(ProfileElement):
+class ProfileElementUSIM(FsProfileElement):
     type = 'usim'

     def __init__(self, decoded: Optional[dict] = None):
@@ -597,7 +628,7 @@
         f = File('ef-imsi', self.decoded['ef-imsi'])
         return dec_imsi(b2h(f.stream.getvalue()))

-class ProfileElementOptUSIM(ProfileElement):
+class ProfileElementOptUSIM(FsProfileElement):
     type = 'opt-usim'

     def __init__(self, decoded: Optional[dict] = None):
@@ -607,7 +638,7 @@
         # provide some reasonable defaults for a MNO-SD
         self.decoded['templateID'] = str(oid.ADF_USIMopt_not_by_default_v2)

-class ProfileElementISIM(ProfileElement):
+class ProfileElementISIM(FsProfileElement):
     type = 'isim'

     def __init__(self, decoded: Optional[dict] = None):
@@ -623,7 +654,7 @@
     def adf_name(self) -> str:
         return b2h(self.decoded['adf-isim'][0][1]['dfName'])

-class ProfileElementOptISIM(ProfileElement):
+class ProfileElementOptISIM(FsProfileElement):
     type = 'opt-isim'

     def __init__(self, decoded: Optional[dict] = None):

--
To view, visit https://gerrit.osmocom.org/c/pysim/+/37619?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ie2791c10289eb28daed2904467b0c5e5b11c94c2
Gerrit-Change-Number: 37619
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <[email protected]>
Gerrit-MessageType: newchange

Reply via email to