... | ... | @@ -266,3 +266,326 @@ Let's see some examples from the test directory: |
|
|
[1, 0, 1, '`\x00\x00\x00\x00']
|
|
|
>>> Msg['CalledPartyBCDNumber'][2]['Num'].decode()
|
|
|
'0600000000'
|
|
|
|
|
|
>>> Msg, err = parse_NAS_MO(unhexlify('0748610bf602f8108003c8c2e65e9a5804e060c0405202f810c4c25c0a00570220003103e5e0341302f810040511035758a65d0100c1'))
|
|
|
>>> err
|
|
|
0
|
|
|
>>> show(Msg)
|
|
|
### EMMTrackingAreaUpdateRequest ###
|
|
|
<SecHdr : 0 (No security)>
|
|
|
<ProtDisc : 7 (EMM)>
|
|
|
<Type : 72 (Tracking area update request)>
|
|
|
### NAS_KSI ###
|
|
|
<TSC : 0 ( native security context)>
|
|
|
<Value : 6>
|
|
|
### EPSUpdateType ###
|
|
|
<Active : 0 (No bearer establishment requested)>
|
|
|
<Value : 1 (combined TA/LA updating)>
|
|
|
### OldGUTI ###
|
|
|
<L : 11>
|
|
|
### EPSID ###
|
|
|
<Digit1 : 0xf>
|
|
|
<Odd : 0>
|
|
|
<Type : 6 (GUTI)>
|
|
|
<PLMN : 20801 (France.Orange)>
|
|
|
<MMEGroupID : 0x8003>
|
|
|
<MMECode : 0xc8>
|
|
|
<MTMSI : 0xc2e65e9a>
|
|
|
### UENetCap ###
|
|
|
<T : 88>
|
|
|
<L : 4>
|
|
|
### UENetCap ###
|
|
|
<EEA0 : 1>
|
|
|
<EEA1_128 : 1>
|
|
|
<EEA2_128 : 1>
|
|
|
<EEA3_128 : 0>
|
|
|
<EEA4 : 0>
|
|
|
<EEA5 : 0>
|
|
|
<EEA6 : 0>
|
|
|
<EEA7 : 0>
|
|
|
<EIA0 : 0>
|
|
|
<EIA1_128 : 1>
|
|
|
<EIA2_128 : 1>
|
|
|
<EIA3_128 : 0>
|
|
|
<EIA4 : 0>
|
|
|
<EIA5 : 0>
|
|
|
<EIA6 : 0>
|
|
|
<EIA7 : 0>
|
|
|
<UEA0 : 1>
|
|
|
<UEA1 : 1>
|
|
|
<UEA2 : 0>
|
|
|
<UEA3 : 0>
|
|
|
<UEA4 : 0>
|
|
|
<UEA5 : 0>
|
|
|
<UEA6 : 0>
|
|
|
<UEA7 : 0>
|
|
|
<UCS2 : 0>
|
|
|
<UIA1 : 1>
|
|
|
<UIA2 : 0>
|
|
|
<UIA3 : 0>
|
|
|
<UIA4 : 0>
|
|
|
<UIA5 : 0>
|
|
|
<UIA6 : 0>
|
|
|
<UIA7 : 0>
|
|
|
### OldTAI ###
|
|
|
<T : 82>
|
|
|
### TAI ###
|
|
|
<PLMN : 20801 (France.Orange)>
|
|
|
<TAC : 0xc4c2>
|
|
|
### DRXParam ###
|
|
|
<T : 92>
|
|
|
### DRXParam ###
|
|
|
<SPLIT_PG_CYCLE_CODE : 10>
|
|
|
<DRXCycleLen : 0 (DRX not specified by the MS)>
|
|
|
<SPLITonCCCH : 0>
|
|
|
<NonDRXTimer : 0 (no non-DRX mode after transfer state)>
|
|
|
### EPSBearerCtxtStat ###
|
|
|
<T : 87>
|
|
|
<L : 2>
|
|
|
### EPSBearerCtxtStat ###
|
|
|
<EBI_7 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_6 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_5 : 1 (BEARER CONTEXT-ACTIVE)>
|
|
|
<EBI_4 : 0>
|
|
|
<EBI_3 : 0>
|
|
|
<EBI_2 : 0>
|
|
|
<EBI_1 : 0>
|
|
|
<EBI_0 : 0>
|
|
|
<EBI_15 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_14 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_13 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_12 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_11 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_10 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_9 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
<EBI_8 : 0 (BEARER CONTEXT-INACTIVE)>
|
|
|
### MSNetCap ###
|
|
|
<T : 49>
|
|
|
<L : 3>
|
|
|
<MS_network_capability_value_part: [
|
|
|
<<GEA1_bits: 1>>
|
|
|
<SM_capabilities_via_dedicated_channels: 1>
|
|
|
<SM_capabilities_via_GPRS_channels: 1>
|
|
|
<UCS2_support: 0>
|
|
|
<SS_Screening_Indicator: 1>
|
|
|
<SoLSA_Capability: 0>
|
|
|
<Revision_level_indicator: 1>
|
|
|
<PFC_feature_mode: 1>
|
|
|
<<Extended_GEA_bits: [
|
|
|
<GEA_2: 1>
|
|
|
<GEA_3: 1>
|
|
|
<GEA_4: 0>
|
|
|
<GEA_5: 0>
|
|
|
<GEA_6: 0>
|
|
|
<GEA_7: 0>]>>
|
|
|
<LCS_VA_capability: 0>
|
|
|
<PS_inter_RAT_HO_from_GERAN_to_UTRAN_Iu_mode_capability: 0>
|
|
|
<PS_inter_RAT_HO_from_GERAN_to_E_UTRAN_S1_mode_capability: 0>
|
|
|
<EMM_Combined_procedures_Capability: 1>
|
|
|
<ISR_support: 1>
|
|
|
<SRVCC_to_GERAN_UTRAN_capability: 0>
|
|
|
<EPC_capability: 1>
|
|
|
<NF_capability: 0>
|
|
|
<GERAN_network_sharing_capability: 0>]>
|
|
|
### OldLAI ###
|
|
|
<T : 19>
|
|
|
### LAI ###
|
|
|
<PLMN : 20801 (France.Orange)>
|
|
|
<LAC : 0x0405>
|
|
|
### MSCm2 ###
|
|
|
<T : 17>
|
|
|
<L : 3>
|
|
|
### MSCm2 ###
|
|
|
<spare : 0>
|
|
|
<RevLevel : 2 (MS supporting R99 or later)>
|
|
|
<EarlyCmCap : 1>
|
|
|
<NoA51 : 0>
|
|
|
<RFClass : 7>
|
|
|
<spare : 0>
|
|
|
<PSCap : 1>
|
|
|
<SSScreeningCap : 1 (capability of handling of ellipsis notation and phase 2 error handling)>
|
|
|
<MTSMSCap : 1>
|
|
|
<VBSNotifCap : 0>
|
|
|
<VGCSNotifCap : 0>
|
|
|
<FCFreqCap : 0>
|
|
|
<MSCm3Cap : 1>
|
|
|
<spare : 0>
|
|
|
<LCSVACap : 1>
|
|
|
<UCS2 : 0>
|
|
|
<SoLSACap : 0>
|
|
|
<CMServPrompt : 1>
|
|
|
<A53 : 1>
|
|
|
<A52 : 0>
|
|
|
### VoiceDomPref ###
|
|
|
<T : 93>
|
|
|
<L : 1>
|
|
|
### VoiceDomPref ###
|
|
|
<spare : 0>
|
|
|
<UEUsage : 0 (Voice centric)>
|
|
|
<VoiceDomPref : 0 (CS Voice only)>
|
|
|
### MSNetFeatSupp ###
|
|
|
<T : 12>
|
|
|
### MSNetFeatSupp ###
|
|
|
<spare : 0>
|
|
|
<ExtPeriodTimers : 1>
|
|
|
>>> Msg['OldGUTI'][1].decode()
|
|
|
(6, '20801', 32771, 200, 3269877402L)
|
|
|
|
|
|
This is basically it. For CSN.1-based information elements, the selection of inner part
|
|
|
is not as friendly as with normal objects: the list of objects is available under
|
|
|
the attribute `_list`, and the corresponding value under `_val`:
|
|
|
|
|
|
>>> Msg['MSNetCap'][2]._list[3]
|
|
|
<UCS2_support(CSN1Bit)>
|
|
|
>>> Msg['MSNetCap'][2]._list[3]._name
|
|
|
'UCS2_support'
|
|
|
>>> Msg['MSNetCap'][2]._val[3]
|
|
|
0
|
|
|
|
|
|
## Encoding NAS messages
|
|
|
NAS messages are almost always structured in the same way, with a header indicating
|
|
|
the protocol and type of message, a list of mandatory information elements (those
|
|
|
with variable length are prefixed with a length field), and a list of optional
|
|
|
information elements. Those last ones are all prefixed with a tag field, and eventually
|
|
|
a length field if of variable length.
|
|
|
|
|
|
When instantiating a NAS message class, if no values are passed in the initialization,
|
|
|
the message builds only with mandatory IEs, set with default values:
|
|
|
|
|
|
>>> Msg = MMLocationUpdatingRequest()
|
|
|
>>> show(Msg)
|
|
|
### MMLocationUpdatingRequest ###
|
|
|
<SkipInd : 0>
|
|
|
<ProtDisc : 5 (MM)>
|
|
|
<Seqn : 0>
|
|
|
<Type : 8 (Registration - LOCATION UPDATING REQUEST)>
|
|
|
<CKSN : 0>
|
|
|
### LocUpdateType ###
|
|
|
<FollowOnReq : 0>
|
|
|
<spare : 0>
|
|
|
<Type : 0 (Normal location updating)>
|
|
|
### LAI ###
|
|
|
<PLMN : 000000>
|
|
|
<LAC : 0x0000>
|
|
|
### MSCm1 ###
|
|
|
<spare : 0>
|
|
|
<RevLevel : 2 (MS supporting R99 or later)>
|
|
|
<EarlyCmCap : 0>
|
|
|
<NoA51 : 0>
|
|
|
<RFClass : 0 (class 1)>
|
|
|
### ID ###
|
|
|
<L : 5>
|
|
|
<V : 0xf400000000>
|
|
|
>>> Msg.to_bytes()
|
|
|
'\x05\x08\x00\x00\x00\x00\x00\x00@\x05\xf4\x00\x00\x00\x00'
|
|
|
|
|
|
From here, it is possible to set IEs one by one, and also the optional ones. A list
|
|
|
with all optional IEs is available under the attribute `_opts`. Optional IEs are by
|
|
|
default set to _transparent_, hence it is require to set them _non transparent_, to
|
|
|
make them appear in the message encoding.
|
|
|
|
|
|
Moreover, many IEs with a Length-Value or Tag-Length-Value structure have by default
|
|
|
a value which is a bytes buffer, and a complete IE structure available under the
|
|
|
`_IE_stat` attribute.
|
|
|
This is used to encode and decode the exact structure and replace the default bytes
|
|
|
buffer. To set the IE exact structure, the method `set_IE()` can be used: it will
|
|
|
initialize the IE with provided arguments, and replace the default bytes buffer.
|
|
|
|
|
|
>>> Msg._opts
|
|
|
[(8, 51, <MSCm2 [transparent] : <T : 51><L : 3><V : 0x400000>>), (4, 12, <AddUpdateParams [transparent] : <T : 12><V : 0>>), (4, 13, <DeviceProp [transparent] : <T : 13><V : 0>>), (4, 14, <MSNetFeatSupp [transparent] : <T : 14><V : 0>>)]
|
|
|
>>> Msg['CKSN'].set_val(2)
|
|
|
>>> Msg['LocUpdateType']['Type'].set_val(1)
|
|
|
>>> Msg['LAI'].set_val((u'20810', 0x1234))
|
|
|
>>> Msg['ID'].set_IE(val={'type': 1, 'ident': '208100123456789'}) # Length-Value
|
|
|
>>> Msg['ID']._IE_stat
|
|
|
<ID : >
|
|
|
>>> Msg['ID']._IE
|
|
|
<ID [IMSI] : 208100123456789>
|
|
|
>>> Msg['AddUpdateParams']
|
|
|
<AddUpdateParams [transparent] : <T : 12><V : 0>>
|
|
|
>>> Msg['AddUpdateParams'].set_trans(False)
|
|
|
>>> Msg['AddUpdateParams'].set_IE(val={'CSMO':1, 'CSMT':1})
|
|
|
>>> show(Msg)
|
|
|
### MMLocationUpdatingRequest ###
|
|
|
<SkipInd : 0>
|
|
|
<ProtDisc : 5 (MM)>
|
|
|
<Seqn : 0>
|
|
|
<Type : 8 (Registration - LOCATION UPDATING REQUEST)>
|
|
|
<CKSN : 2>
|
|
|
### LocUpdateType ###
|
|
|
<FollowOnReq : 0>
|
|
|
<spare : 0>
|
|
|
<Type : 1 (Periodic updating)>
|
|
|
### LAI ###
|
|
|
<PLMN : 20810 (France.S.F.R.)>
|
|
|
<LAC : 0x1234>
|
|
|
### MSCm1 ###
|
|
|
<spare : 0>
|
|
|
<RevLevel : 2 (MS supporting R99 or later)>
|
|
|
<EarlyCmCap : 0>
|
|
|
<NoA51 : 0>
|
|
|
<RFClass : 0 (class 1)>
|
|
|
### ID ###
|
|
|
<L : 8>
|
|
|
### ID ###
|
|
|
<Digit1 : 0x2>
|
|
|
<Odd : 1>
|
|
|
<Type : 1 (IMSI)>
|
|
|
<Digits : 0x80011032547698>
|
|
|
### AddUpdateParams ###
|
|
|
<T : 12>
|
|
|
### AddUpdateParams ###
|
|
|
<spare : 0>
|
|
|
<CSMO : 1 (CS fallback MO call)>
|
|
|
<CSMT : 1 (CS fallback MT call)>
|
|
|
>>> Msg.to_bytes()
|
|
|
'\x05\x08!\x02\xf8\x01\x124@\x08)\x80\x01\x102Tv\x98\xc3'
|
|
|
|
|
|
It is also possible to prepare a _dict_ containing all IEs values that are required
|
|
|
to appear in the message, and to initialize the message class with it. In this way,
|
|
|
all optional IEs that are set, will appear directly in the message encoding:
|
|
|
|
|
|
>>> IEs = {}
|
|
|
>>> IEs['CKSN']= 4
|
|
|
>>> IEs['LocUpdateType'] = {'Type': 1}
|
|
|
>>> IEs['LAI'] = (u'20820', 0x4321)
|
|
|
>>> IEs['ID'] = {'type': 1, 'ident': '208209876543210'}
|
|
|
>>> IEs['AddUpdateParams'] = {'CSMO': 1, 'CSMT': 1}
|
|
|
>>> IEs
|
|
|
{'LocUpdateType': {'Type': 1}, 'ID': {'ident': '208209876543210', 'type': 1}, 'AddUpdateParams': {'CSMT': 1, 'CSMO': 1}, 'CKSN': 4, 'LAI': (u'20820', 17185)}
|
|
|
>>> Msg = MMLocationUpdatingRequest(val=IEs)
|
|
|
>>> show(Msg)
|
|
|
### MMLocationUpdatingRequest ###
|
|
|
<SkipInd : 0>
|
|
|
<ProtDisc : 5 (MM)>
|
|
|
<Seqn : 0>
|
|
|
<Type : 8 (Registration - LOCATION UPDATING REQUEST)>
|
|
|
<CKSN : 4>
|
|
|
### LocUpdateType ###
|
|
|
<FollowOnReq : 0>
|
|
|
<spare : 0>
|
|
|
<Type : 1 (Periodic updating)>
|
|
|
### LAI ###
|
|
|
<PLMN : 20820 (France.Bouygues Telecom)>
|
|
|
<LAC : 0x4321>
|
|
|
### MSCm1 ###
|
|
|
<spare : 0>
|
|
|
<RevLevel : 2 (MS supporting R99 or later)>
|
|
|
<EarlyCmCap : 0>
|
|
|
<NoA51 : 0>
|
|
|
<RFClass : 0 (class 1)>
|
|
|
### ID ###
|
|
|
<L : 8>
|
|
|
### ID ###
|
|
|
<Digit1 : 0x2>
|
|
|
<Odd : 1>
|
|
|
<Type : 1 (IMSI)>
|
|
|
<Digits : 0x80028967452301>
|
|
|
### AddUpdateParams ###
|
|
|
<T : 12>
|
|
|
### AddUpdateParams ###
|
|
|
<spare : 0>
|
|
|
<CSMO : 1 (CS fallback MO call)>
|
|
|
<CSMT : 1 (CS fallback MT call)>
|
|
|
>>> Msg.to_bytes()
|
|
|
'\x05\x08A\x02\xf8\x02C!@\x08)\x80\x02\x89gE#\x01\xc3' |