Change in pysim[master]: filesystem: Introduce 'construct' support

laforge gerrit-no-reply at lists.osmocom.org
Sat Apr 10 22:02:56 UTC 2021


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/23709 )


Change subject: filesystem: Introduce 'construct' support
......................................................................

filesystem: Introduce 'construct' support

This allows for pure declarative encoders/decoders for linear fixed
and transparent EFs.

Change-Id: Id0765ec3ddb8c044838ce47d0ff8740720a32b15
---
M pySim/construct.py
M pySim/filesystem.py
2 files changed, 36 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/09/23709/1

diff --git a/pySim/construct.py b/pySim/construct.py
index 03d284e..839497c 100644
--- a/pySim/construct.py
+++ b/pySim/construct.py
@@ -1,5 +1,5 @@
 from construct import *
-from pySim.utils import b2h, h2b
+from pySim.utils import b2h, h2b, swap_nibbles
 
 """Utility code related to the integration of the 'construct' declarative parser."""
 
@@ -26,6 +26,13 @@
     def _encode(self, obj, context, path):
         return h2b(obj)
 
+class BcdAdapter(Adapter):
+    """convert a bytes() type to a string of BCD nibbles."""
+    def _decode(self, obj, context, path):
+        return swap_nibbles(b2h(obj))
+    def _encode(self, obj, context, path):
+        return h2b(swap_nibbles(obj))
+
 def filter_dict(d, exclude_prefix='_'):
     """filter the input dict to ensure no keys starting with 'exclude_prefix' remain."""
     res = {}
diff --git a/pySim/filesystem.py b/pySim/filesystem.py
index e771f3c..49520c3 100644
--- a/pySim/filesystem.py
+++ b/pySim/filesystem.py
@@ -35,6 +35,7 @@
 from typing import cast, Optional, Iterable, List, Any, Dict, Tuple
 
 from pySim.utils import sw_match, h2b, b2h, is_hex
+from pySim.construct import filter_dict
 from pySim.exceptions import *
 from pySim.jsonpath import js_path_find, js_path_modify
 
@@ -466,6 +467,7 @@
             size : tuple of (minimum_size, recommended_size)
         """
         super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, parent=parent)
+        self._construct = None
         self.size = size
         self.shell_commands = [self.ShellCommands()]
 
@@ -487,6 +489,8 @@
         method = getattr(self, '_decode_hex', None)
         if callable(method):
             return method(b2h(raw_bin_data))
+        if self._construct:
+            return filter_dict(self._construct.parse(raw_bin_data, total_len=len(raw_bin_data)))
         return {'raw': raw_bin_data.hex()}
 
     def decode_hex(self, raw_hex_data:str) -> dict:
@@ -508,6 +512,8 @@
         method = getattr(self, '_decode_bin', None)
         if callable(method):
             return method(raw_bin_data)
+        if self._construct:
+            return filter_dict(self._construct.parse(raw_bin_data, total_len=len(raw_bin_data)))
         return {'raw': raw_bin_data.hex()}
 
     def encode_bin(self, abstract_data:dict) -> bytearray:
@@ -528,6 +534,8 @@
         method = getattr(self, '_encode_hex', None)
         if callable(method):
             return h2b(method(abstract_data))
+        if self._construct:
+            return self._construct.build(abstract_data)
         raise NotImplementedError
 
     def encode_hex(self, abstract_data:dict) -> str:
@@ -549,6 +557,8 @@
         if callable(method):
             raw_bin_data = method(abstract_data)
             return b2h(raw_bin_data)
+        if self._construct:
+            return b2h(self._construct.build(abstract_data))
         raise NotImplementedError
 
 
@@ -683,6 +693,7 @@
         super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, parent=parent)
         self.rec_len = rec_len
         self.shell_commands = [self.ShellCommands()]
+        self._construct = None
 
     def decode_record_hex(self, raw_hex_data:str) -> dict:
         """Decode raw (hex string) data into abstract representation.
@@ -703,6 +714,8 @@
         method = getattr(self, '_decode_record_bin', None)
         if callable(method):
             return method(raw_bin_data)
+        if self._construct:
+            return filter_dict(self._construct.parse(raw_bin_data, total_len=len(raw_bin_data)))
         return {'raw': raw_bin_data.hex()}
 
     def decode_record_bin(self, raw_bin_data:bytearray) -> dict:
@@ -724,6 +737,8 @@
         method = getattr(self, '_decode_record_hex', None)
         if callable(method):
             return method(raw_hex_data)
+        if self._construct:
+            return filter_dict(self._construct.parse(raw_bin_data, total_len=len(raw_bin_data)))
         return {'raw': raw_hex_data}
 
     def encode_record_hex(self, abstract_data:dict) -> str:
@@ -745,6 +760,8 @@
         if callable(method):
             raw_bin_data = method(abstract_data)
             return b2h(raw_bin_data)
+        if self._construct:
+            return b2h(self._construct.build(abstract_data))
         raise NotImplementedError
 
     def encode_record_bin(self, abstract_data:dict) -> bytearray:
@@ -765,6 +782,8 @@
         method = getattr(self, '_encode_record_hex', None)
         if callable(method):
             return h2b(method(abstract_data))
+        if self._construct:
+            return self._construct.build(abstract_data)
         raise NotImplementedError
 
 class CyclicEF(LinFixedEF):
@@ -813,10 +832,12 @@
         method = getattr(self, '_decode_record_hex', None)
         if callable(method):
             return method(raw_hex_data)
+        raw_bin_data = h2b(raw_hex_data)
         method = getattr(self, '_decode_record_bin', None)
         if callable(method):
-            raw_bin_data = h2b(raw_hex_data)
             return method(raw_bin_data)
+        if self._construct:
+            return filter_dict(self._construct.parse(raw_bin_data, total_len=len(raw_bin_data)))
         return {'raw': raw_hex_data}
 
     def decode_record_bin(self, raw_bin_data:bytearray) -> dict:
@@ -838,6 +859,8 @@
         method = getattr(self, '_decode_record_hex', None)
         if callable(method):
             return method(raw_hex_data)
+        if self._construct:
+            return filter_dict(self._construct.parse(raw_bin_data, total_len=len(raw_bin_data)))
         return {'raw': raw_hex_data}
 
     def encode_record_hex(self, abstract_data:dict) -> str:
@@ -858,6 +881,8 @@
         method = getattr(self, '_encode_record_bin', None)
         if callable(method):
             return b2h(method(abstract_data))
+        if self._construct:
+            return b2h(filter_dict(self._construct.build(abstract_data)))
         raise NotImplementedError
 
     def encode_record_bin(self, abstract_data:dict) -> bytearray:
@@ -878,6 +903,8 @@
         method = getattr(self, '_encode_record_hex', None)
         if callable(method):
             return h2b(method(abstract_data))
+        if self._construct:
+            return filter_dict(self._construct.build(abstract_data))
         raise NotImplementedError
 
     def _decode_bin(self, raw_bin_data:bytearray):

-- 
To view, visit https://gerrit.osmocom.org/c/pysim/+/23709
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Id0765ec3ddb8c044838ce47d0ff8740720a32b15
Gerrit-Change-Number: 23709
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210410/eeed9924/attachment.htm>


More information about the gerrit-log mailing list