... | ... | @@ -419,9 +419,8 @@ of the object: |
|
|
}
|
|
|
|
|
|
Here, only the first level of content is returned. The *get_proto()* method returns the complete
|
|
|
content by entering each constructed content recursively. **Be careful** about some limitations of
|
|
|
this method: its call on a recursive object will trigger a Python recursion exception... Moreover
|
|
|
it does not provides hints on optional components (those marked OPTIONAL or with a DEFAULT value),
|
|
|
content by entering each constructed content recursively. **Be careful** about the main limitation of
|
|
|
this method: it does not provides hints on optional components (those marked OPTIONAL or with a DEFAULT value),
|
|
|
neither on component in the root or extension part of the content.
|
|
|
|
|
|
>>> SIC.get_proto()
|
... | ... | @@ -449,6 +448,19 @@ neither on component in the root or extension part of the content. |
|
|
}
|
|
|
}
|
|
|
|
|
|
Regarding the mandatory or optional content of a constructed object, one can use the
|
|
|
following attributes: *_root_mand*, *_root_opt* and *_ext*. The first lists all mandatory
|
|
|
components from the root part: those need to be set with a value to conform to the ASN.1
|
|
|
specification. The 2nd and 3rd list components that are OPTIONAL, have a DEFAULT value,
|
|
|
or are in the extension part ; thus, they are all optional. This means you are not required
|
|
|
to set them with a value to conform to the ASN.1 specification.
|
|
|
|
|
|
>>> SIC._root_mand
|
|
|
['mib', 'sysInfoType1', 'sysInfoType3', 'sysInfoType5', 'sysInfoType7']
|
|
|
>>> SIC._root_opt
|
|
|
['sysInfoTypeSB1', 'sysInfoTypeSB2', 'sysInfoType11', 'sysInfoType11bis', 'sysInfoType12', 'vb50NonCriticalExtensions']
|
|
|
>>> SIC._ext # this one is None, because System-Information-Container is not extensible
|
|
|
|
|
|
Because the UMTS RRC protocol is using the UPER encoding, we will use the *from_uper()*
|
|
|
method to deserialize buffers. The corresponding value will be available in the *_val* attribute,
|
|
|
and will also be returned when calling the ASN.1 object itself. Finally, the *to_asn1()*
|
... | ... | @@ -508,8 +520,8 @@ radio interfaces: it saves bandwidth. |
|
|
As seen in the previous example, it is required to know the content of constructed objects
|
|
|
to be able to access their internals, and also to be able to set values. Two utility functions
|
|
|
are provided to help with that:
|
|
|
- *get_obj_at(Obj, path)*
|
|
|
- *get_val_at(Obj, path)*
|
|
|
- *get_at(Obj, path)* to navigate within an ASN.1 object
|
|
|
- *get_val_at(Obj, path)* to navigate within the value assigned to an ASN.1 object
|
|
|
|
|
|
Both take an ASN.1 object and the path to one of its internal component or value and return it.
|
|
|
Here are some examples with the previous *PCCH_Message* object:
|
... | ... | @@ -524,7 +536,7 @@ Here are some examples with the previous *PCCH_Message* object: |
|
|
spare: 'NULL'
|
|
|
}
|
|
|
}
|
|
|
>>> get_obj_at(pcch, ['message', 'pagingType1', 'pagingRecordList', None, 'utran-Identity'])
|
|
|
>>> get_at(pcch, ['message', 'pagingType1', 'pagingRecordList', None, 'utran-Identity'])
|
|
|
<utran-Identity (SEQUENCE)>
|
|
|
>>> # pagingRecordList being a SEQUENCE OF, no need to provide any name to select its content
|
|
|
>>> get_val_at(pcch, ['message', 'pagingType1', 'pagingRecordList', 2])
|
... | ... | @@ -1326,9 +1338,9 @@ and re-encoding an InitialDP operation CAP message, that is handled by the ASN.1 |
|
|
>>> get_val_at(M, ['begin', 'components', 0, 'basicROS', 'invoke', 'argument', 'InitialDPArg', 'locationInformation'])
|
|
|
{'vlr-number': b'\x913f\x02\x00\x00\xf0', 'cellGlobalIdOrServiceAreaIdOrLAI': ('cellGlobalIdOrServiceAreaIdFixedLength', b'1234567')}
|
|
|
>>> # let's modify the locationInformation
|
|
|
>>> get_obj_at(M, ['begin', 'components', 0, 'basicROS', 'invoke', 'argument', 'InitialDPArg', 'locationInformation', 'cellGlobalIdOrServiceAreaIdOrLAI'])
|
|
|
>>> get_at(M, ['begin', 'components', 0, 'basicROS', 'invoke', 'argument', 'InitialDPArg', 'locationInformation', 'cellGlobalIdOrServiceAreaIdOrLAI'])
|
|
|
<cellGlobalIdOrServiceAreaIdOrLAI ([CellGlobalIdOrServiceAreaIdOrLAI] CHOICE)>
|
|
|
>>> get_obj_at(M, ['begin', 'components', 0, 'basicROS', 'invoke', 'argument', 'InitialDPArg', 'locationInformation', 'cellGlobalIdOrServiceAreaIdOrLAI'])._cont
|
|
|
>>> get_at(M, ['begin', 'components', 0, 'basicROS', 'invoke', 'argument', 'InitialDPArg', 'locationInformation', 'cellGlobalIdOrServiceAreaIdOrLAI'])._cont
|
|
|
{
|
|
|
cellGlobalIdOrServiceAreaIdFixedLength: <cellGlobalIdOrServiceAreaIdFixedLength ([CellGlobalIdOrServiceAreaIdFixedLength] OCTET STRING)>,
|
|
|
laiFixedLength: <laiFixedLength ([LAIFixedLength] OCTET STRING)>
|
... | ... | |