-
Notifications
You must be signed in to change notification settings - Fork 130
Mobile nas messages
All the NAS-related messages are available in the pycrate_mobile directory.
The following modules provide structures for dealing with 2G and 3G NAS messages:
- TS24008_MM: contains all structures for Mobility Management messages
- TS24008_CC: for Call Control
- TS24008_GMM: for GPRS Mobility Management
- TS24008_SM: for GPRS Session Management
All those structures are corresponding mostly to the descriptions from section 9 of the 3GPP TS 24.008 specification. They are themselves using IEs (Information Elements) defined in section 10 of the specification, and available in the module TS24008_IE, with the exception of IEs for GPRS using CSN.1, which are defined in the pycrate_csn1dir directory.
For SMS and Supplementary Services, other modules are available:
- TS24011_PPSMS: for Point-to-Point Short Message Service, which itself calls
- TS23040_SMS: for SMS itself
- TS24080_SS: for Supplementary Service, which wraps some ASN.1-defined objects from the pycrate_asn1dir/SS.py module.
For LTE NAS, two main modules are available:
- TS24301_EMM: for EPS Mobility Management
- TS24301_ESM: for EPS Session Management Those structures are corresponding to the descriptions from section 8 of the 3GPP TS 24.301 specification. IEs defined in section 9 are available in the module TS24301_IE. Moreover, in case the CryptoMobile library is installed and can be imported, the EMMSecProtNASMessage and EMMServiceRequest classes have methods dedicated to the LTE NAS cryptographic operations.
All classes representing NAS messages and information elements are deriving from few base classes defined in the TS24007 module, which implements some specific aspects of cellular layer 3 message structures as defined in the TS 24.007 3GPP specification.
Finally, two top-level modules are enabling the import of most of those NAS messages' structures and providing custom functions for decoding any cellular NAS messages:
Currently (december 2017), the 2G RRM module (in TS44018_RR.py) is almost empty. Some work is needed to implement all 2G RRM messages and extend the support of the CSN.1 translater for supporting specific padding patterns (used e.g. in 2G system information messages).
Some more esoteric (understand much less used) mostly 2G-oriented protocols are not implemented (i.e. Group and Broadcast Call Control, GTTP and LCS).
In order to decode NAS messages, the simplest way is to used one of the two functions used in the NAS module:
- parse_NAS_MO(buf) -> (element, err), for parsing Mobile Originating message (i.e. uplink)
- parse_NAS_MT(buf) -> (element, err), for parsing Mobile Terminating message (i.e. downlink)
In case there is an error during the decoding of the buffer, this will be returned in
the err code, with a code corresponding to standard 3GPP NAS error code (e.g. which can be
used in a Status NAS message in return).
The element contains an Element's instance (or None, if the whole decoding failed), with
the while message header and information elements.
Let's see some examples from the test directory:
>>> from pycrate_mobile.NAS import *
>>> Msg, err = parse_NAS_MO(unhexlify('05080200f11040005705f44c6a94c033035758a6'))
>>> err
0
>>> show(Msg)
### MMLocationUpdatingRequest ###
<SkipInd : 0>
<ProtDisc : 5 (MM)>
<Seqn : 0>
<Type : 8 (Registration - LOCATION UPDATING REQUEST)>
<CKSN : 0>
### LocUpdateType ###
<FollowOnReq : 0>
<spare : 0>
<Type : 2 (IMSI attach)>
### LAI ###
<PLMN : 00101>
<LAC : 0x4000>
### MSCm1 ###
<spare : 0>
<RevLevel : 2 (MS supporting R99 or later)>
<EarlyCmCap : 1>
<NoA51 : 0>
<RFClass : 7>
### ID ###
<L : 5>
### ID ###
<Digit1 : 0xf>
<Odd : 0>
<Type : 4 (TMSI)>
<TMSI : 0x4c6a94c0>
### MSCm2 ###
<T : 51>
<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>
>>> Msg['LAI'].get_val()
['\x00\xf1\x10', 16384]
>>> Msg['LAI'].decode() # some IEs have a specific .decode() method, like the LAI / PLMN, or the ID here
('00101', 16384)
>>> Msg['ID'][1]
<ID [TMSI] : 0x4c6a94c0>
>>> Msg['ID'][1].get_val()
[15, 0, 4, 1282053312]
>>> Msg['ID'][1].decode()
(4, 1282053312)
>>>
>>> Msg, err = parse_NAS_MO(unhexlify('034504066004020005815e068160000000001502010040080402600400021f00'))
>>> err
0
>>> show(Msg)
### CCSetupMO ###
<TIFlag : 0 (initiator)>
<TIO : 0>
<ProtDisc : 3 (CC)>
<Seqn : 1>
<Type : 5 (Call establishment - SETUP)>
### BearerCap1 ###
<T : 4>
<L : 6>
### BearerCap ###
<Ext : 0>
<RadioChanReq : 3 (dual rate support MS/full rate preferred)>
<CodingStd : 0 (GSM standardized coding)>
<TransferMode : 0 (circuit)>
<InfoTransferCap : 0 (speech)>
### Ext3a ###
<Ext : 0>
<Coding : 0 (octet used for extension of information transfer capability)>
<CTM : 0 (CTM text telephony is not supported)>
<spare : 0>
<SpeechVersionInd : 4 (GSM FR v3 (FR AMR))>
### Ext3b ###
### _BearerCapExt3bRec ###
<Ext : 0>
<Coding : 0 (octet used for extension of information transfer capability)>
<spare : 0>
<SpeechVersionInd : 2 (GSM FR v2 (GSM EFR))>
### _BearerCapExt3bRec ###
<Ext : 0>
<Coding : 0 (octet used for extension of information transfer capability)>
<spare : 0>
<SpeechVersionInd : 0 (GSM FR v1 (GSM FR))>
### _BearerCapExt3bRec ###
<Ext : 0>
<Coding : 0 (octet used for extension of information transfer capability)>
<spare : 0>
<SpeechVersionInd : 5 (GSM HR v3 (HR AMR))>
### _BearerCapExt3bRec ###
<Ext : 1>
<Coding : 0 (octet used for extension of information transfer capability)>
<spare : 0>
<SpeechVersionInd : 1 (GSM HR v1 (GSM HR))>
### CalledPartyBCDNumber ###
<T : 94>
<L : 6>
### CalledPartyBCDNumber ###
<Ext : 1>
<Type : 0 (unknown)>
<NumberingPlan : 1 (ISDN / telephony numbering plan (E.164 / E.163))>
<Num : 0600000000>
### CCCap ###
<T : 21>
<L : 2>
### CCCap ###
<MaxNumSupportedBearers : 0>
<MultimediaCAT : 0>
<ENICM : 0>
<PCP : 0>
<DTMF : 1>
<spare : 0>
<MaxNumSpeechBearers : 0>
### SupportedCodecs ###
<T : 64>
<L : 8>
### SupportedCodecs ###
### CodecSysID ###
<SysID : 4 (UMTS)>
<BMLen : 2>
### CodecBM ###
<TDMA_EFR : 0>
<UMTS_AMR2 : 1>
<UMTS_AMR : 1>
<HR_AMR : 0>
<FR_AMR : 0>
<GSM_EFR : 0>
<GSM_HR : 0>
<GSM_FR : 0>
<reserved : 0>
<reserved : 0>
<OHR_AMR-WB : 0>
<OFR_AMR-WB : 0>
<OHR_AMR : 0>
<UMTS_AMR-WB : 1>
<FR_AMR-WB : 0>
<PDC_EFR : 0>
<spare : ''>
### CodecSysID ###
<SysID : 0 (GSM)>
<BMLen : 2>
### CodecBM ###
<TDMA_EFR : 0>
<UMTS_AMR2 : 0>
<UMTS_AMR : 0>
<HR_AMR : 1>
<FR_AMR : 1>
<GSM_EFR : 1>
<GSM_HR : 1>
<GSM_FR : 1>
<reserved : 0>
<reserved : 0>
<OHR_AMR-WB : 0>
<OFR_AMR-WB : 0>
<OHR_AMR : 0>
<UMTS_AMR-WB : 0>
<FR_AMR-WB : 0>
<PDC_EFR : 0>
<spare : ''>
>>> show(Msg['CalledPartyBCDNumber'][2])
### CalledPartyBCDNumber ###
<Ext : 1>
<Type : 0 (unknown)>
<NumberingPlan : 1 (ISDN / telephony numbering plan (E.164 / E.163))>
<Num : 0600000000>
>>> Msg['CalledPartyBCDNumber'][2].get_val()
[1, 0, 1, '`\x00\x00\x00\x00']
>>> Msg['CalledPartyBCDNumber'][2]['Num'].decode()
'0600000000'