mirror of https://gerrit.osmocom.org/pysim
pySim/tlv.py: Fix TLV_IE_Collection from_dict with nested collections
This is all quite complicated. In general, the TLV_IE.to_dict() method obviously is expected to return a dict (with key equal to the snake-case name of the class, value to the decode IE value). This single-entry dict can then be passed back to the from_dict() method to build the binary representation. However, with a TLV_IE_Collection, any TLV_IE can occur any number of times, so we need an array to represent it (dict would need unique key, which doesn't exist in multiple instances of same TLV IE). Hence, the TLV_IE_Collection.to_dict() method actually returns a list of dicts, rather than a dict itself. Each dict in the list represents one TLV_IE. When encoding such a TLV_IE_Collection back from the list-of-dicts, we so far didn't handle this special case and tried to de-serialize with a class-name-keyed dict, which doesn't work. This patch fixes a regression in the aram_store_ref_ar_do pySim-shell command which got introduced in Change-Id I3dd5204510e5c32ef1c4a999258d87cb3f1df8c8 While we're fixing it, add some additional comments to why things are how they are. Change-Id: Ibdd30cf1652c864f167b1b655b49a87941e15fd5
This commit is contained in:
parent
ba955b650e
commit
2352f2dcdd
13
pySim/tlv.py
13
pySim/tlv.py
|
@ -386,12 +386,21 @@ class TLV_IE_Collection(metaclass=TlvCollectionMeta):
|
|||
of dicts, where they key indicates the name of the TLV_IE subclass to use."""
|
||||
# list of instances of TLV_IE collection member classes appearing in the data
|
||||
res = []
|
||||
# iterate over members of the list passed into "decoded"
|
||||
for i in decoded:
|
||||
# iterate over all the keys (typically one!) within the current list item dict
|
||||
for k in i.keys():
|
||||
# check if we have a member identified by the dict key
|
||||
if k in self.members_by_name:
|
||||
# resolve the class for that name; create an instance of it
|
||||
cls = self.members_by_name[k]
|
||||
inst = cls()
|
||||
inst.from_dict({k: i[k]})
|
||||
if cls.nested_collection_cls:
|
||||
# in case of collections, we want to pass the raw "value" portion to from_dict,
|
||||
# as to_dict() below intentionally omits the collection-class-name as key
|
||||
inst.from_dict(i[k])
|
||||
else:
|
||||
inst.from_dict({k: i[k]})
|
||||
res.append(inst)
|
||||
else:
|
||||
raise ValueError('%s: Unknown TLV Class %s in %s; expected %s' %
|
||||
|
@ -400,6 +409,8 @@ class TLV_IE_Collection(metaclass=TlvCollectionMeta):
|
|||
return res
|
||||
|
||||
def to_dict(self):
|
||||
# we intentionally return not a dict, but a list of dicts. We could prefix by
|
||||
# self.__class__.__name__, but that is usually some meaningless auto-generated collection name.
|
||||
return [x.to_dict() for x in self.children]
|
||||
|
||||
def to_bytes(self):
|
||||
|
|
Loading…
Reference in New Issue