dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/38195?usp=email )
Change subject: filesystem: pass total_len to construct of when encoding file contents ......................................................................
filesystem: pass total_len to construct of when encoding file contents
In our construct models we frequently use a context parameter "total_len", we also pass this parameter to construct when we decode files, but we do not pass it when we generate files. This is a problem, because when total_len is used in the construct model, this parameter must be known also when decoding the file.
Let's make sure that the total_len is properly determined and and passed to construct (via pyosmocom)
Related: OS#5714 Change-Id: I1b7a51594fbc5d9fe01132c39354a2fa88d53f9b --- M pySim/filesystem.py M pySim/runtime.py M requirements.txt 3 files changed, 36 insertions(+), 16 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/95/38195/1
diff --git a/pySim/filesystem.py b/pySim/filesystem.py index 43a72f2..5258569 100644 --- a/pySim/filesystem.py +++ b/pySim/filesystem.py @@ -179,7 +179,7 @@ """Return a dict of {'identifier': self} tuples.
Args: - alias : Add an alias with given name to 'self' + alias : Add an alias with given name to 'self' flags : Specify which selectables to return 'FIDS' and/or 'NAMES'; If not specified, all selectables will be returned. Returns: @@ -743,7 +743,17 @@ return t.to_dict() return {'raw': raw_bin_data.hex()}
- def encode_bin(self, abstract_data: dict) -> bytearray: + def _get_size(self, total_len : int = None): + if total_len is not None: + return {"total_len" : total_len} + elif self.size[1] is not None: + return {"total_len" : self.size[1]} + elif self.size[0] is not None: + return {"total_len" : self.size[0]} + else: + return {"total_len" : None} + + def encode_bin(self, abstract_data: dict, total_len : int = None) -> bytearray: """Encode abstract representation into raw (binary) data.
A derived class would typically provide an _encode_bin() or _encode_hex() method @@ -762,7 +772,7 @@ if callable(method): return h2b(method(abstract_data)) if self._construct: - return build_construct(self._construct, abstract_data) + return build_construct(self._construct, abstract_data, self._get_size(total_len)) if self._tlv: t = self._tlv() if inspect.isclass(self._tlv) else self._tlv t.from_dict(abstract_data) @@ -770,7 +780,7 @@ raise NotImplementedError( "%s encoder not yet implemented. Patches welcome." % self)
- def encode_hex(self, abstract_data: dict) -> str: + def encode_hex(self, abstract_data: dict, total_len : int = None) -> str: """Encode abstract representation into raw (hex string) data.
A derived class would typically provide an _encode_bin() or _encode_hex() method @@ -790,7 +800,7 @@ raw_bin_data = method(abstract_data) return b2h(raw_bin_data) if self._construct: - return b2h(build_construct(self._construct, abstract_data)) + return b2h(build_construct(self._construct, abstract_data, self._get_size(total_len))) if self._tlv: t = self._tlv() if inspect.isclass(self._tlv) else self._tlv t.from_dict(abstract_data) @@ -1030,7 +1040,17 @@ return t.to_dict() return {'raw': raw_hex_data}
- def encode_record_hex(self, abstract_data: dict, record_nr: int) -> str: + def __get_rec_len(self, total_len : int = None): + if total_len is not None: + return {"total_len" : total_len} + elif self.rec_len[1] is not None: + return {"total_len" : self.rec_len[1]} + elif self.rec_len[0] is not None: + return {"total_len" : self.rec_len[0]} + else: + return {"total_len" : None} + + def encode_record_hex(self, abstract_data: dict, record_nr: int, total_len: int = None) -> str: """Encode abstract representation into raw (hex string) data.
A derived class would typically provide an _encode_record_bin() or _encode_record_hex() @@ -1051,7 +1071,7 @@ raw_bin_data = method(abstract_data, record_nr=record_nr) return b2h(raw_bin_data) if self._construct: - return b2h(build_construct(self._construct, abstract_data)) + return b2h(build_construct(self._construct, abstract_data, self.__get_rec_len(total_len))) if self._tlv: t = self._tlv() if inspect.isclass(self._tlv) else self._tlv t.from_dict(abstract_data) @@ -1059,7 +1079,7 @@ raise NotImplementedError( "%s encoder not yet implemented. Patches welcome." % self)
- def encode_record_bin(self, abstract_data: dict, record_nr : int) -> bytearray: + def encode_record_bin(self, abstract_data: dict, record_nr : int, total_len : int = None) -> bytearray: """Encode abstract representation into raw (binary) data.
A derived class would typically provide an _encode_record_bin() or _encode_record_hex() @@ -1079,7 +1099,7 @@ if callable(method): return h2b(method(abstract_data, record_nr=record_nr)) if self._construct: - return build_construct(self._construct, abstract_data) + return build_construct(self._construct, abstract_data, self.__get_rec_len(total_len)) if self._tlv: t = self._tlv() if inspect.isclass(self._tlv) else self._tlv t.from_dict(abstract_data) @@ -1224,7 +1244,7 @@ return t.to_dict() return {'raw': raw_hex_data}
- def encode_record_hex(self, abstract_data: dict) -> str: + def encode_record_hex(self, abstract_data: dict, total_len : int = None) -> str: """Encode abstract representation into raw (hex string) data.
A derived class would typically provide an _encode_record_bin() or _encode_record_hex() @@ -1243,7 +1263,7 @@ if callable(method): return b2h(method(abstract_data)) if self._construct: - return b2h(filter_dict(build_construct(self._construct, abstract_data))) + return b2h(filter_dict(build_construct(self._construct, abstract_data, self._get_size(total_len)))) if self._tlv: t = self._tlv() if inspect.isclass(self._tlv) else self._tlv t.from_dict(abstract_data) @@ -1251,7 +1271,7 @@ raise NotImplementedError( "%s encoder not yet implemented. Patches welcome." % self)
- def encode_record_bin(self, abstract_data: dict) -> bytearray: + def encode_record_bin(self, abstract_data: dict, total_len : int = None) -> bytearray: """Encode abstract representation into raw (binary) data.
A derived class would typically provide an _encode_record_bin() or _encode_record_hex() @@ -1270,7 +1290,7 @@ if callable(method): return h2b(method(abstract_data)) if self._construct: - return filter_dict(build_construct(self._construct, abstract_data)) + return filter_dict(build_construct(self._construct, abstract_data, self._get_size(total_len))) if self._tlv: t = self._tlv() if inspect.isclass(self._tlv) else self._tlv t.from_dict(abstract_data) diff --git a/pySim/runtime.py b/pySim/runtime.py index 898008e..5281857 100644 --- a/pySim/runtime.py +++ b/pySim/runtime.py @@ -518,7 +518,7 @@ Args: data : abstract data which is to be encoded and written """ - data_hex = self.selected_file.encode_hex(data) + data_hex = self.selected_file.encode_hex(data, self.selected_file_size()) return self.update_binary(data_hex)
def read_record(self, rec_nr: int = 0): @@ -568,7 +568,7 @@ rec_nr : Record number to read data_hex : Abstract data to be written """ - data_hex = self.selected_file.encode_record_hex(data, rec_nr) + data_hex = self.selected_file.encode_record_hex(data, rec_nr, self.selected_file_record_len()) return self.update_record(rec_nr, data_hex)
def retrieve_data(self, tag: int = 0): diff --git a/requirements.txt b/requirements.txt index 99fd5f9..25e3654 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ jsonpath-ng construct>=2.9.51 bidict -pyosmocom>=0.0.2 +pyosmocom>=0.0.3 pyyaml>=5.1 termcolor colorlog