Closed jewalt closed 2 years ago
You are touching here some limits of pycrate. The CSN.1 part has been developped with pure decoding in mind, but no specific routines were developped to ease encoding fields and accessing subfields. There are 2 crude approaches to accessing a subfield value in CSN.1. The first by going directly through the value of the SIB13, the 2nd by browsing the JSON representation:
In [53]: from pycrate_mobile.NAS import *
In [54]: m, e = parse_NAS_MT(unhexlify('010600901278487CC932A62C25A4CB2B2B2B2B2B2B2B2B'), True)
In [55]: e # 0 means no error during decoding
Out[55]: 0
In [56]: print(m['SI13RestOctets']['si_13_rest_octets'].show()) # focusing on the SI13 rest octets
<si_13_rest_octets (CSN1List): [
<(CSN1Alt): { H : [
<bcch_change_mark (CSN1Bit): 1>
<si_change_field (CSN1Bit): 0>
<(CSN1Alt): { 0 : []}>
<(CSN1Alt): { 0 : [
<rac (CSN1Bit): 73>
<spgc_ccch_sup (CSN1Bit): 1>
<priority_access_thr (CSN1Bit): 6>
<network_control_order (CSN1Bit): 0>
<gprs_cell_options (CSN1Ref): <gprs_cell_options_ie (CSN1List): [
<nmo (CSN1Bit): 1>
<t3168 (CSN1Bit): 1>
<t3192 (CSN1Bit): 0>
<drx_timer_max (CSN1Bit): 3>
<access_burst_type (CSN1Bit): 1>
<control_ack_type (CSN1Bit): 1>
<bs_cv_max (CSN1Bit): 9>
<(CSN1Alt): { 1 : [
<pan_dec (CSN1Bit): 1>
<pan_inc (CSN1Bit): 1>
<pan_max (CSN1Bit): 1>]}>
<(CSN1Alt): { 1 : [
<extension_length (CSN1Bit): 10>
<(CSN1Ref): <extension_information (CSN1List): [
<(CSN1List): [
<(CSN1Alt): { 1 : [
<egprs_packet_channel_request (CSN1Bit): 0>
<bep_period (CSN1Bit): 6>]}>
<pfc_feature_mode (CSN1Bit): 0>
<dtm_support (CSN1Bit): 0>
<bss_paging_coordination (CSN1Bit): 1>]>
<(CSN1List): [
<ccn_active (CSN1Bit): 0>
<nw_ext_utbf (CSN1Bit): 1>]>]>>]}>]>>
<gprs_power_control_parameters (CSN1Ref): <gprs_power_control_parameters_ie (CSN1List): [
<alpha (CSN1Bit): 8>
<t_avg_w (CSN1Bit): 9>
<t_avg_t (CSN1Bit): 13>
<pc_meas_chan (CSN1Bit): 0>
<n_avg_i (CSN1Bit): 4>]>>]}>
<(CSN1Alt): { H : [
<sgsnr (CSN1Bit): 1>
<(CSN1Alt): { H : [
<si_status_ind (CSN1Bit): 0>
<(CSN1Alt): { L : []}>]}>]}>]}>
<(CSN1Ref): <spare_padding (CSN1Val): L**>>]>
In [57]: m['SI13RestOctets']['si_13_rest_octets'].get_val() # we access here the CSN.1 value decoded
Out[57]:
[['H',
1,
0,
['0'],
['0',
73,
1,
6,
0,
[1,
1,
0,
3,
1,
1,
9,
['1', 1, 1, 1],
['1', 10, [[['1', 0, 6], 0, 0, 1], [0, 1]]]],
[8, 9, 13, 0, 4]],
['H', 1, ['H', 0, ['L']]]],
['L',
'L',
[...]
'L']]
In [58]: rac = m['SI13RestOctets']['si_13_rest_octets'].get_val()[0][4][1] # here, [0][4][1] is the path to the RAC value
In [59]: print(m['SI13RestOctets']['si_13_rest_octets'].to_json()) # here is the JSON representation of the rest octets
{
"si_13_rest_octets": [
[
"H",
{
"bcch_change_mark": "001"
},
{
"si_change_field": "0000"
},
[
"0"
],
[
"0",
{
"rac": "01001001"
},
{
"spgc_ccch_sup": "1"
},
{
"priority_access_thr": "110"
},
{
"network_control_order": "00"
},
{
"gprs_cell_options": {
"gprs_cell_options_ie": [
{
"nmo": "01"
},
{
"t3168": "001"
},
{
"t3192": "000"
},
{
"drx_timer_max": "011"
},
{
"access_burst_type": "1"
},
{
"control_ack_type": "1"
},
{
"bs_cv_max": "1001"
},
[
"1",
{
"pan_dec": "001"
},
{
"pan_inc": "001"
},
{
"pan_max": "001"
}
],
[
"1",
{
"extension_length": "001010"
},
{
"extension_information": [
[
[
"1",
{
"egprs_packet_channel_request": "0"
},
{
"bep_period": "0110"
}
],
{
"pfc_feature_mode": "0"
},
{
"dtm_support": "0"
},
{
"bss_paging_coordination": "1"
}
],
[
{
"ccn_active": "0"
},
{
"nw_ext_utbf": "1"
}
]
]
}
]
]
}
},
{
"gprs_power_control_parameters": {
"gprs_power_control_parameters_ie": [
{
"alpha": "1000"
},
{
"t_avg_w": "01001"
},
{
"t_avg_t": "01101"
},
{
"pc_meas_chan": "0"
},
{
"n_avg_i": "0100"
}
]
}
}
],
[
"H",
{
"sgsnr": "1"
},
[
"H",
{
"si_status_ind": "0"
},
[
"L"
]
]
]
],
{
"spare_padding": [
"L",
"L",
[...]
"L"
]
}
]
}
In [60]: m['SI13RestOctets']['si_13_rest_octets']._to_jval() # and here is the underlying Python value ready for JSON encoding
Out[60]:
[['H',
{'bcch_change_mark': '001'},
{'si_change_field': '0000'},
['0'],
['0',
{'rac': '01001001'},
{'spgc_ccch_sup': '1'},
{'priority_access_thr': '110'},
{'network_control_order': '00'},
{'gprs_cell_options': {'gprs_cell_options_ie': [{'nmo': '01'},
{'t3168': '001'},
{'t3192': '000'},
{'drx_timer_max': '011'},
{'access_burst_type': '1'},
{'control_ack_type': '1'},
{'bs_cv_max': '1001'},
['1', {'pan_dec': '001'}, {'pan_inc': '001'}, {'pan_max': '001'}],
['1',
{'extension_length': '001010'},
{'extension_information': [[['1',
{'egprs_packet_channel_request': '0'},
{'bep_period': '0110'}],
{'pfc_feature_mode': '0'},
{'dtm_support': '0'},
{'bss_paging_coordination': '1'}],
[{'ccn_active': '0'}, {'nw_ext_utbf': '1'}]]}]]}},
{'gprs_power_control_parameters': {'gprs_power_control_parameters_ie': [{'alpha': '1000'},
{'t_avg_w': '01001'},
{'t_avg_t': '01101'},
{'pc_meas_chan': '0'},
{'n_avg_i': '0100'}]}}],
['H', {'sgsnr': '1'}, ['H', {'si_status_ind': '0'}, ['L']]]],
{'spare_padding': ['L',
'L',
'L',
[...]
'L']}]
In [61]: m['SI13RestOctets']['si_13_rest_octets']._to_jval()[0][4][1] # so we can also access the RAC value here in a similar way
Out[61]: {'rac': '01001001'}
As you can see however, there is no magic to browse through all the different subfields of a CSN.1 structure. You need to know the path of what you are looking for.
Thank you! This gets me what I needed.
I have been struggling in trying to find the proper way to access data values in GSM SIB rest_octet fields. For example, SIB13 RAC field.
In this SIB13 message: 010600901278487CC932A62C25A4CB2B2B2B2B2B2B2B2B
I know the RAC is 73 by using tshark to parse the SIB13 message, but I am not sure the best way to index into the decoded object to get that data. Any help would be really appreciated.