Closed nickvsnetworking closed 2 years ago
You may re-read https://github.com/P1sec/pycrate/wiki/Using-the-pycrate-asn1-runtime#rrc-3g : I just added a short section on attributes indicating optional components of constructed types. Besides of this, there is no magic however, as a protocol developer, you are required to know the content of the message structures to fill them appropriately.
Moreover, those 2 exiting issues may be related to yours: https://github.com/P1sec/pycrate/issues/104 https://github.com/P1sec/pycrate/issues/83 They were unfortunately never solved or completed.
Sorry to say, but maybe your development can wait till January.
Maybe you could already contribute to the project by submitting the SBC-AP ASN.1 protocol definition to the pycrate_asn1dir subdirectory ? That would be very nice. Also apart from this, thank you for all the valuable information you provide on your blog !
Thanks @p1-bmu ,
I'll send a PR with the latest ASN1 definition for SBc-AP and some examples when I've got this working.
As you suggested calling the names returned a list of what I needed to populate which is exactly what I was after:
>>> SBC.SBC_AP_PDU_Contents.Write_Replace_Warning_Indication_IEs
<Write-Replace-Warning-Indication-IEs ([SBC-AP-PROTOCOL-IES] CLASS): ASN1Set(root=[{'id': 5, 'criticality': 'reject', 'Value': <Value ([Message-Identifier] BIT STRING)>, 'presence': 'mandatory'}, {'id': 11, 'criticality': 'reject', 'Value': <Value ([Serial-Number] BIT STRING)>, 'presence': 'mandatory'}, {'id': 23, 'criticality': 'reject', 'Value': <Value ([Broadcast-Scheduled-Area-List] SEQUENCE)>, 'presence': 'optional'}], ext=[])>
And with fresh eyes and another read over the documentation I managed to make some progress!
To create a Write-Replace-Warning-Request I need to include the two mandatory protocolIEs which are:
Which I set in a list named _protocolies and try and compile using the set_val() function:
import SBC
sbc_asn1_object = SBC.SBC_AP_PDU_Descriptions.SBC_AP_PDU
#id 5 [Message-Identifier] BIT STRING
#id 11 [Serial-Number] BIT STRING
#Contents generated from running: SBC.SBC_AP_PDU_Contents.Write_Replace_Warning_Indication_IEs
protocol_ies = [] #Empty list to store protocol IEs
protocol_ies.append({'id': 5, u'Value': (int(4379), 16)}) #Message-Identifier
protocol_ies.append({'id': 11, u'Value': (int(4379), 16)}) #Serial-Number
value = ('initiatingMessage', \
{'procedureCode': 0, 'criticality': 'ignore', \
'value': ('Write-Replace-Warning-Request', {'protocolIEs': protocol_ies })})
sbc_asn1_object.set_val(value)
sbc_hex_out = binascii.hexlify(sbc_asn1_object.to_aper())
sbc_hex_out = sbc_hex_out.decode("utf-8")
However when I try to run it I get the below, which I think relates to the BIT STRING encoding on the Message-Identifier, which I think I've got correct? (With (int(4379), 16)
being a 2-tuple of positive int (bit string uint value, bit string length) as per the docs)
self._cont._safechk_val(v)
File "/usr/local/lib/python3.8/dist-packages/pycrate-0.4-py3.8.egg/pycrate_asn1rt/asnobj_construct.py", line 748, in _safechk_val
raise(ASN1ObjErr('{0}: invalid value, {1!r}'.format(self.fullname(), val)))
pycrate_asn1rt.err.ASN1ObjErr: Write-Replace-Warning-Request.protocolIEs._item_: invalid value, {'id': 5, 'Value': (4379, 16)}
Any pointers? I know it's probably something dead simple. (The upper case V in value is used in the SBC.py library, which is compiled from the ASN1 definition attached to the first post.
I parsed some S1 messages with some of the example code, and looked at the Maco-eNodeB-ID as that's also encoded as BIT STRING and confirmed the way I'm formatting it is the same as on the S1 messages, so I'm a bit out of ideas?
This is a special case with all RAN protocols, where the Value
field of each ProtocolIE is an OPEN type, and then depend of its id
. So you need to provide the reference to the specific type you put in Value
:
protocol_ies.append({'id': 5, 'Value': ('Message-Identifier', (4379, 16))})
protocol_ies.append({'id': 11, 'Value': ('Serial-Number', (4379, 16))})
Thanks again @p1-bmu ,
That makes sense we need to define the reference to the type of value,
I just tried running it with the changes you specified, same result though:
File "/usr/local/lib/python3.8/dist-packages/pycrate-0.4-py3.8.egg/pycrate_asn1rt/asnobj_construct.py", line 748, in _safechk_val
raise(ASN1ObjErr('{0}: invalid value, {1!r}'.format(self.fullname(), val)))
pycrate_asn1rt.err.ASN1ObjErr: Write-Replace-Warning-Request.protocolIEs._item_: invalid value, {'id': 5, 'Value': ('Message-Identifier', (4379, 16))}
Is there something else I'm missing?
I've attached the simplified Python script and contents of SBc.py generated by PyCrate for the ASN.1 dict,
I'd appreciate any pointers, I know I've got a lot more IEs to populate after this, but hopefully once I know how to format one I can format all the others accordingly.
I guess you need to set also the criticality
component in each protocolIE
(see the definition of the ProtocolIE-Field object).
Any additional feedback @nickvsnetworking ? Or I'll close this.
Hi! I got there in the end with this, here's the code I used for anyone trying this themselves:
##Write-Replace-Warning-Request
list_of_tais = [\
{'tai': {'pLMNidentity': bytes.fromhex(plmn_hex), 'tAC': b'\x4BB'}}]
warning_area_list = ('cell-ID-List', [{'pLMNidentity': bytes.fromhex(plmn_hex), 'cell-ID': (167772161, 28)}, {'pLMNidentity': bytes.fromhex(plmn_hex), 'cell-ID': (167772162, 28), 'iE-Extensions': [{'id': 199, 'criticality': 'reject', 'extensionValue': ('_unk_004', b'\x99\x99\x99\x99')}]}])
value = ('initiatingMessage', {'procedureCode': 0, 'criticality': 'reject', 'value': \
('Write-Replace-Warning-Request', {'protocolIEs': [\
{'id': 5, 'criticality': 'reject', 'value': ('Message-Identifier', (4370, 16))}, \
{'id': 11, 'criticality': 'reject', 'value': ('Serial-Number', (43995, 16))}, \
#{'id': 14, 'criticality': 'reject', 'value': ('List-of-TAIs', list_of_tais)}, \
#{'id': 15, 'criticality': 'ignore', 'value': ('Warning-Area-List', warning_area_list)}, \
{'id': 10, 'criticality': 'reject', 'value': ('Repetition-Period', 30)}, \
#{'id': 21, 'criticality': 'reject', 'value': ('Extended-Repetition-Period', 8192)}, \
{'id': 7, 'criticality': 'reject', 'value': ('Number-of-Broadcasts-Requested', 1)}, \
{'id': 18, 'criticality': 'ignore', 'value': ('Warning-Type', b'\x01\x02')}, \
#{'id': 17, 'criticality': 'ignore', 'value': ('Warning-Security-Information', b'\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1')}, \
#{'id': 3, 'criticality': 'ignore', 'value': ('Data-Coding-Scheme', (85, 8))}, \
#{'id': 16, 'criticality': 'ignore', 'value': ('Warning-Message-Content', b'\x01' + b'Test Alert Message - Please ignore')}, \
#The phrase Emergency!
{'id': 16, 'criticality': 'ignore', 'value': ('Warning-Message-Content', bytes.fromhex('01c576597e2ebbc7f950a8d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d1000a'))}, \
#{'id': 19, 'criticality': 'ignore', 'value': ('Omc-Id', b'\x01')}, \
#{'id': 20, 'criticality': 'reject', 'value': ('Concurrent-Warning-Message-Indicator', 'true')}\
]})})
sbc_asn1_object.set_val(value)
sbc_hex_out = binascii.hexlify(sbc_asn1_object.to_aper())
sbc_hex_out = sbc_hex_out.decode("utf-8")
Hi folks,
Apologies in advance for what may very well be a dumb question, I've had a read over the Wiki and the outputted code and it's still not clear to me:
I'm playing with the 3GPP SBc Interface which is ASN.1 encoded,
Using the magic of Pycrate I've created a Python file from the ASN1 definition and using it I'm able to take hex data containing an encoded ASN.1 message and turn it into a Python tuple - fantastic.
And I'm also able to encode a tuple back into ASN.1 using the _setval() function:
Considering the ASN.1 definition defines what elements need to be present and which are optional, I'm wondering if there is a function to generate list the required elements to be fed into set_val?
Manually populating the tuples from the elements in the spec seems above what my mind can process at this point in the year,
SBC.asn.txt SBC.py.txt