module L3_Templates { /* L3 Templates, building on top of MobileL3*_Types from Ericsson. * * (C) 2017-2018 by Harald Welte * All rights reserved. * * Released under the terms of GNU General Public License, Version 2 or * (at your option) any later version. */ import from General_Types all; import from Osmocom_Types all; import from MobileL3_Types all; import from MobileL3_CommonIE_Types all; import from MobileL3_MM_Types all; import from MobileL3_RRM_Types all; import from MobileL3_CC_Types all; import from MobileL3_GMM_SM_Types all; import from MobileL3_SMS_Types all; /* TS 24.007 Table 11.3 TI Flag */ const BIT1 c_TIF_ORIG := '0'B; const BIT1 c_TIF_REPL := '1'B; type enumerated CmServiceType { CM_TYPE_MO_CALL ('0001'B), CM_TYPE_EMERG_CALL ('0010'B), CM_TYPE_MO_SMS ('0100'B), CM_TYPE_SS_ACT ('1000'B), CM_TYPE_VGCS ('1001'B), CM_TYPE_VBS ('1010'B), CM_TYPE_LCS ('1011'B) } template ML3_Cause_TLV ts_ML3_Cause(BIT7 cause, BIT4 loc := '0001'B, BIT2 std := '11'B) := { elementIdentifier := '08'O, lengthIndicator := 0, /* overwritten */ oct3 := { location := loc, spare1_1 := '0'B, codingStandard := std, ext1 := '0'B, recommendation := omit, ext2 := omit }, oct4 := { causeValue := cause, ext3 := '1'B }, diagnostics := omit } /* send template fro Mobile Identity (TMSI) */ template MobileIdentityLV ts_MI_TMSI_LV(OCT4 tmsi) := { lengthIndicator := 0, /* overwritten */ mobileIdentityV := { typeOfIdentity := '000'B, /* overwritten */ oddEvenInd_identity := { tmsi_ptmsi := { oddevenIndicator := '0'B, fillerDigit := '1111'B, octets := tmsi } } } } /* send template fro Mobile Identity (TMSI) */ function ts_MI_TMSI_TLV(template (omit) OCT4 tmsi) return template (omit) MobileIdentityTLV { var template (omit) MobileIdentityTLV ret; if (istemplatekind(tmsi, "omit")) { return omit; } else { ret := { elementIdentifier := '0100011'B, spare1 := '0'B, mobileIdentityLV := ts_MI_TMSI_LV(valueof(tmsi)) } return ret; } } template MobileIdentityTLV ts_MI_IMEISV_TLV(hexstring imeisv) := { elementIdentifier := '0100011'B, spare1 := '0'B, mobileIdentityLV := ts_MI_IMEISV_LV(imeisv) } private function f_enc_IMSI_L3(hexstring digits) return IMSI_L3 { var IMSI_L3 l3; var integer len := lengthof(digits); if (len rem 2 == 1) { /* modulo remainder */ l3.oddevenIndicator := '1'B; l3.fillerDigit := omit; } else { l3.oddevenIndicator := '0'B; l3.fillerDigit := '1111'B; } l3.digits := digits; return l3; } private function f_enc_IMEI_L3(hexstring digits) return IMEI_L3 { var IMEI_L3 l3; var integer len := lengthof(digits); if (len rem 2 == 1) { /* modulo remainder */ l3.oddevenIndicator := '1'B; } else { l3.oddevenIndicator := '0'B; } l3.digits := digits; return l3; } private function f_enc_IMEI_SV(hexstring digits) return IMEI_SV { var IMEI_SV l3; var integer len := lengthof(digits); if (len rem 2 == 1) { /* modulo remainder */ l3.oddevenIndicator := '1'B; } else { l3.oddevenIndicator := '0'B; } l3.digits := digits; l3.fillerDigit := '1111'B; return l3; } /* send template fro Mobile Identity (IMSI) */ template (value) MobileIdentityLV ts_MI_IMSI_LV(hexstring imsi_digits) := { lengthIndicator := 0, /* overwritten */ mobileIdentityV := { typeOfIdentity := '001'B, oddEvenInd_identity := { imsi := f_enc_IMSI_L3(imsi_digits) } } } /* send template fro Mobile Identity (IMEI) */ template (value) MobileIdentityLV ts_MI_IMEI_LV(hexstring imei_digits) := { lengthIndicator := 0, /* overwritten */ mobileIdentityV := { typeOfIdentity := '010'B, oddEvenInd_identity := { imei := f_enc_IMEI_L3(imei_digits) } } } /* send template fro Mobile Identity (IMEISV) */ template (value) MobileIdentityLV ts_MI_IMEISV_LV(hexstring imei_digits) := { lengthIndicator := 0, /* overwritten */ mobileIdentityV := { typeOfIdentity := '011'B, oddEvenInd_identity := { imei_sv := f_enc_IMEI_SV(imei_digits) } } } /* Send template for Classmark 2 */ template (value) MobileStationClassmark2_LV ts_CM2 := { lengthIndicator := 0, rf_PowerCapability := '000'B, a5_1 := '0'B, esind := '1'B, revisionLevel := '10'B, spare1_1 := '0'B, mobileStationClassmark2_oct4 := { fc := '1'B, vgcs := '0'B, vbs := '0'B, sm_Capability := '1'B, ss_ScreenIndicator := '01'B, ps_Capability := '1'B, spare2_1 := '0'B }, mobileStationClassmark2_oct5 := { a5_2 := '0'B, a5_3 := '1'B, cmsp := '0'B, solsa := '0'B, ucs2 := '0'B, lcsva_cap := '0'B, spare5_7 :='0'B, cm3 := '0'B } }; /* Send template for CM SERVICE REQUEST */ template (value) PDU_ML3_MS_NW ts_CM_SERV_REQ(CmServiceType serv_type, MobileIdentityLV mi_lv) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { cMServiceRequest := { messageType := '000000'B, /* overwritten */ nsd := '00'B, cm_ServiceType := int2bit(enum2int(serv_type), 4), cipheringKeySequenceNumber := { '000'B, '0'B }, mobileStationClassmark2 := ts_CM2, mobileIdentity := mi_lv, priorityLevel := omit, additionalUpdateParameterTV := omit, deviceProperties := omit } } } } template (value) CipheringKeySequenceNumberV ts_CKSN(integer key_seq) := { keySequence := int2bit(key_seq, 3), spare := '0'B } /* Send template for CM RE-ESTABLISH REQUEST */ template (value) PDU_ML3_MS_NW ts_CM_REEST_REQ(integer cksn, MobileIdentityLV mi_lv) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { cMReEstablReq := { messageType := '101000'B, /* overwritten */ nsd := '00'B, cipheringKeySequenceNumber := ts_CKSN(cksn), spare := '0000'B, mobileStationClassmark2 := ts_CM2, mobileIdentityLV := mi_lv, locationAreaIdentification := omit, deviceProperties := omit } } } } template PDU_ML3_NW_MS tr_MT_simple(template BIT4 discr := ?) := { discriminator := discr, tiOrSkip := { skipIndicator := '0000'B }, msgs := ? } template PDU_ML3_NW_MS tr_CM_SERV_ACC := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { cMServiceAccept := { messageType := '100001'B, nsd := ? } } } } template PDU_ML3_NW_MS tr_CM_SERV_REJ(template OCT1 rej_cause := ?) := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { cMServiceReject := { messageType := '100010'B, nsd := ?, rejectCause := rej_cause, t3246_Value := * } } } } template PDU_ML3_NW_MS tr_PAGING_REQ1(template MobileIdentityLV mi1 := ?, template MobileIdentityTLV mi2 := *) := { discriminator := '0110'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { pagingReq_Type1 := { messageType := '00100001'B, pageMode := ?, channelNeeded := ?, mobileIdentity1 := mi1, mobileIdentity2 := mi2, p1RestOctets := ? } } } } template PDU_ML3_NW_MS tr_PAGING_REQ2(template TMSIP_TMSI_V mi1 := ?, template TMSIP_TMSI_V mi2 := ?, template MobileIdentityTLV mi3 := *) := { discriminator := '0110'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { pagingReq_Type2 := { messageType := '00100010'B, pageMode := ?, channelNeeded := ?, mobileIdentity1 := mi1, mobileIdentity2 := mi2, mobileIdentity3 := mi3, p2RestOctets := ? } } } } template PDU_ML3_NW_MS tr_PAGING_REQ3(template TMSIP_TMSI_V mi1 := ?, template TMSIP_TMSI_V mi2 := ?, template TMSIP_TMSI_V mi3 := ?, template TMSIP_TMSI_V mi4 := ?) := { discriminator := '0110'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { pagingReq_Type3 := { messageType := '00100100'B, pageMode := ?, channelNeeded := ?, mobileIdentity1 := mi1, mobileIdentity2 := mi2, mobileIdentity3 := mi3, mobileIdentity4 := mi4, p3RestOctets := ? } } } } /* Send template for PAGING RESPONSE */ template (value) PDU_ML3_MS_NW ts_PAG_RESP(MobileIdentityLV mi_lv) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { pagingResponse := { messageType := '00000000'B, /* overwritten */ cipheringKeySequenceNumber := { '000'B, '0'B }, spare1_4 := '0000'B, mobileStationClassmark := ts_CM2, mobileIdentity := mi_lv, additionalUpdateParameters := omit } } } } template (value) PDU_ML3_MS_NW ts_RRM_ModeModifyAck(ChannelDescription2_V desc, ChannelMode_V mode) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { channelModeModifyAck := { messageType := '00010111'B, channelDescription := desc, channelMode := mode, extendedTSCSet := omit } } } } template (value) PDU_ML3_NW_MS ts_RRM_CiphModeCmd(BIT3 alg_id) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { cipheringModeCommand := { messageType := '00110101'B, cipherModeSetting := { sC := '1'B, algorithmIdentifier := alg_id }, cipherModeResponse := { cR := '0'B, spare := '000'B } } } } } template (value) PDU_ML3_MS_NW ts_RRM_CiphModeCompl := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { cipheringModeComplete := { messageType := '00110010'B, mobileEquipmentIdentity := omit } } } } template (value) PDU_ML3_MS_NW ts_RRM_AssignmentComplete(OCT1 cause) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { assignmentComplete := { messageType := '00101001'B, rR_Cause := { valuePart := cause } } } } } template (value) PDU_ML3_MS_NW ts_RRM_AssignmentFailure(OCT1 cause) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { assignmentFailure := { messageType := '00101111'B, rR_Cause := { valuePart := cause } } } } } template (value) PDU_ML3_MS_NW ts_RRM_HandoverFailure(OCT1 cause) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { handoverFailure := { messageType := '00101000'B, rRCause := { valuePart := cause }, pSCause := omit } } } } template (value) PDU_ML3_MS_NW ts_RRM_HandoverComplete(OCT1 cause) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { handoverComplete := { messageType := '00101100'B, rRCause := { valuePart := cause }, mobileObsservedTimeDiff := omit, mobileTimeDifferenceHyperframe := omit } } } } function ts_CM3_TLV(template (omit) OCTN cm3) return template MobileStationClassmark3_TLV { if (not isvalue(cm3)) { return omit; } var template MobileStationClassmark3_TLV ret := { elementIdentifier := '20'O, lengthIndicator := 0, /* overwritten */ valuePart := cm3 } return ret; } template (value) PDU_ML3_MS_NW ts_RRM_CM_CHG(MobileStationClassmark2_LV cm2, template (omit) MobileStationClassmark3_TLV cm3 := omit) := { discriminator := '0110'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { classmarkChange := { messageType := '00010110'B, mobileStationClassmark2 := cm2, mobileStationClassmark3 := cm3 } } } } template (value) PDU_ML3_MS_NW ts_RRM_UL_REL(OCT1 cause) := { discriminator := '0110'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { uplinkRelease := { messageType := '00001110'B, rR_Cause := { valuePart := cause } } } } } template PDU_ML3_MS_NW tr_RRM_RR_STATUS(template OCT1 cause := ?) := { discriminator := '0110'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { rrm := { rR_Status := { messageType := '00010010'B, rR_Cause := { valuePart := cause } } } } } template PDU_ML3_MS_NW ts_ML3_MO := { discriminator := '0000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := ? } template LocationUpdatingType ts_ML3_IE_LuType := { lut := ?, spare1_1 := '0'B, fop := '0'B } template LocationUpdatingType ts_ML3_IE_LuType_Normal modifies ts_ML3_IE_LuType := { lut := '00'B } template LocationUpdatingType ts_ML3_IE_LuType_Periodic modifies ts_ML3_IE_LuType := { lut := '01'B } template LocationUpdatingType ts_ML3_IE_LuType_Attach modifies ts_ML3_IE_LuType := { lut := '10'B } template CipheringKeySequenceNumberV ts_ML3_IE_CKSN(integer cksn) := { keySequence := int2bit(cksn, 3), spare := '0'B } template PDU_ML3_MS_NW ts_ML3_MO_LU_Req(LocationUpdatingType lu_type, LocationAreaIdentification_V lai, MobileIdentityLV mi, MobileStationClassmark1_V cm1) modifies ts_ML3_MO := { msgs := { mm := { locationUpdateRequest := { messageType := '001000'B, nsd := '00'B, /* ? */ locationUpdatingType := lu_type, cipheringKeySequenceNumber := ts_ML3_IE_CKSN(0), locationAreaIdentification := lai, mobileStationClassmark1 := cm1, mobileIdentityLV := mi, classmarkInformationType2_forUMTS := omit, additionalUpdateParameterTV := omit, deviceProperties := omit, mS_NetworkFeatureSupport := omit } } } } template PDU_ML3_MS_NW ts_ML3_MO_TmsiRealloc_Cmpl modifies ts_ML3_MO := { msgs := { mm := { tmsiReallocComplete := { messageType := '011011'B, nsd := '00'B } } } } template PDU_ML3_NW_MS tr_ML3_MT_LU_Acc := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { locationUpdateAccept := { messageType := '000010'B, nsd := '00'B, locationAreaIdentification := ?, mobileIdentityTLV := *, followOnProceed := *, cTS_Permission := *, equivalentPLMNs := *, emergencyNumberList := *, perMS_T3212 := * } } } } template PDU_ML3_NW_MS tr_ML3_MT_LU_Rej(template OCT1 cause := ?) := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { locationUpdateReject := { messageType := '000100'B, nsd := '00'B, rejectCause := cause, t3246_Value := * } } } } template PDU_ML3_NW_MS tr_ML3_MT_MM_ID_Req(template BIT3 id_type := ?) := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { identityRequest := { messageType := '011000'B, nsd := '00'B, identityType := id_type, spare1_5 := ? } } } } template PDU_ML3_MS_NW ts_ML3_MO_MM_ID_Rsp(MobileIdentityLV mi) modifies ts_ML3_MO := { msgs := { mm := { identityResponse := { messageType := '011001'B, nsd := '00'B, mobileIdentityLV := mi, p_TMSI_TypeTV := omit, routingAreaIdentification2TLV := omit, p_TMSISignature2TLV := omit } } } } template PDU_ML3_MS_NW ts_ML3_MO_MM_ID_Rsp_IMSI(hexstring imsi) := ts_ML3_MO_MM_ID_Rsp(valueof(ts_MI_IMSI_LV(imsi))); template PDU_ML3_MS_NW ts_ML3_MO_MM_ID_Rsp_IMEI(hexstring imei) := ts_ML3_MO_MM_ID_Rsp(valueof(ts_MI_IMEI_LV(imei))); template (value) MobileStationClassmark1_V ts_CM1(BIT1 a5_1_unavail := '0'B, BIT2 rev := '10'B, BIT1 esind := '1'B) := { rf_PowerCapability := '010'B, a5_1 := a5_1_unavail, esind := esind, revisionLevel := rev, spare1_1 := '0'B } template PDU_ML3_MS_NW ts_ML3_MO_MM_IMSI_DET_Ind(MobileIdentityLV mi, template MobileStationClassmark1_V cm1 := ts_CM1) modifies ts_ML3_MO := { msgs := { mm := { imsiDetachIndication := { messageType := '000001'B, nsd := '00'B, mobileStationClassmark1 := cm1, mobileIdentityLV := mi } } } } template PDU_ML3_MS_NW ts_ML3_MO_CC(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_ORIG, tIExtension := omit } } } template (value) CalledPartyBCD_Number ts_Called(hexstring digits) := { elementIdentifier := '5E'O, lengthIndicator := 0, /* overwritten */ numberingPlanIdentification := '0000'B, typeOfNumber := '000'B, /* unknown */ ext1 := '0'B, digits := digits } template CalledPartyBCD_Number tr_Called(template hexstring digits) := { elementIdentifier := '5E'O, lengthIndicator := ?, numberingPlanIdentification := ?, typeOfNumber := ?, ext1 := ?, digits := digits } template CallingPartyBCD_Number tr_Calling(template hexstring digits) := { elementIdentifier := '5C'O, lengthIndicator := ?, oct3 := ?, digits := digits } type integer SpeechVer; template (value) Speech_AuxiliarySpeech ts_SpeechAux(SpeechVer ver, BIT1 suffix) := { speechVersionIndication := int2bit(ver-1,3) & suffix, spare1_1 := '0'B, cTM_or_Spare := '0'B, coding := '0'B, extension_octet_3a_3b := '0'B } template (value) Speech_AuxiliarySpeech ts_SpeechAuxFR(SpeechVer ver) := ts_SpeechAux(ver, '0'B); template (value) Speech_AuxiliarySpeech ts_SpeechAuxHR(SpeechVer ver) := ts_SpeechAux(ver, '1'B); template (value) BearerCapability_TLV ts_Bcap_voice := { elementIdentifier := '04'O, lengthIndicator := 0, /* overwritten */ octet3 := { informationTransferCapability := '000'B, transferMode := '0'B, codingStandard := '0'B, radioChannelRequirement := '11'B, /* FR preferred */ extension_octet_3 := '0'B, /* overwritten */ speech_aux_3a_3b := { valueof(ts_SpeechAuxHR(3)), valueof(ts_SpeechAuxFR(3)), valueof(ts_SpeechAuxFR(2)), valueof(ts_SpeechAuxFR(1)), valueof(ts_SpeechAuxHR(1)) } }, octet4 := omit, octet5 := omit, octet6 := omit, octet7 := omit } template PDU_ML3_MS_NW ts_ML3_MO_CC_SETUP(integer tid, hexstring called, template BearerCapability_TLV bcap := ts_Bcap_voice) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { cc := { setup_MS_NW := { messageType := '000101'B, nsd := '00'B, bcRepeatIndicator := omit, bearerCapability1 := bcap, bearerCapability2 := omit, facility := omit, callingPartySubAddress := omit, calledPartyBCD_Number := ts_Called(called), calledPartySubAddress := omit, llc_RepeatIndicator := omit, lowLayerCompatibility1 := omit, lowLayerCompatibility2 := omit, hlc_RepeatIndicator := omit, highLayerCompatibility1 := omit, highLayerCompatibility2 := omit, user_user := omit, ss_VersionIndicator := omit, clir_Suppression := omit, clir_Invocation := omit, cC_Capabilities := omit, facility_ccbs1 := omit, facility_ccbs2 := omit, streamIdentifier := omit, supportedCodecs := omit, redial := omit } } } } template PDU_ML3_MS_NW ts_ML3_MO_CC_EMERG_SETUP(integer tid, template BearerCapability_TLV bcap := ts_Bcap_voice) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { cc := { emergencySetup := { messageType := '001110'B, nsd := '00'B, bearerCapability := bcap, streamIdentifier := omit, supportedCodecs := omit, emergencyCategory := omit } } } } template PDU_ML3_NW_MS tr_ML3_MT_CC_CALL_PROC(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ?, tIExtension := omit } }, msgs := { cc := { callProceeding := { messageType := '000010'B, nsd := '00'B, repeatIndicator := *, bearerCapability1 := *, bearerCapability2 := *, facility := *, progressIndicator := *, priorityGranted := *, networkCCCapabilities := * } } } } template PDU_ML3_NW_MS tr_ML3_MT_CC_ALERTING(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ?, tIExtension := omit } }, msgs := { cc := { alerting_NW_MS := { messageType := '000001'B, nsd := '00'B, facility := *, progressIndicator := *, user_user := * } } } } template PDU_ML3_MS_NW ts_ML3_MO_CC_ALERTING(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { cc := { alerting_MS_NW := { messageType := '000001'B, nsd := '00'B, facility := omit, user_user := omit, ss_VersionIndicator := omit } } } } template PDU_ML3_MS_NW ts_ML3_MT_CC_ALERTING(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { cc := { alerting_MS_NW := { messageType := '000001'B, nsd := '00'B, facility := omit, user_user := omit, ss_VersionIndicator := omit } } } } template PDU_ML3_MS_NW ts_ML3_MO_CC_CONNECT(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { cc := { connect_MS_NW := { messageType := '000111'B, nsd := '00'B, facility := omit, connectedSubAddress := omit, user_user := omit, ss_VersionIndicator := omit, streamIdentifier := omit } } } } template PDU_ML3_NW_MS tr_ML3_MT_CC_CONNECT(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { cc := { connect_NW_MS := { messageType := '000111'B, nsd := '00'B, facility := *, progressIndicator := *, connectedNumber := *, connectedSubAddress := *, user_user := * } } } } template (value) PDU_ML3_MS_NW ts_ML3_MO_CC_CONNECT_ACK(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { cc := { connectAck := { messageType := '001111'B, nsd := '00'B } } } } template (value) PDU_ML3_MS_NW ts_ML3_MO_CC_START_DTMF(integer tid, charstring number) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { cc := { startDTMF := { messageType := '110101'B, nsd := '00'B, keypadFacility := { elementIdentifier := '2C'O, keypadInformation := int2bit(char2int(number), 7), spare_1 := '0'B } } } } } template PDU_ML3_NW_MS tr_ML3_MT_CC_DISC(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ?, tIExtension := omit } }, msgs := { cc := { disconnect_NW_MS := { messageType := '100101'B, nsd := '00'B, cause := ?, facility := *, progressIndicator := *, user_user := *, allowedActions := * } } } } template PDU_ML3_NW_MS tr_ML3_MT_CC_RELEASE(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ?, tIExtension := omit } }, msgs := { cc := { release_NW_MS := { messageType := '101101'B, nsd := '00'B, cause := ?, secondCause := *, facility := *, user_user := * } } } } template PDU_ML3_MS_NW ts_ML3_MO_CC_RELEASE(integer tid, BIT1 tid_remote, BIT7 cause) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := tid_remote, tIExtension := omit } }, msgs := { cc := { release_MS_NW := { messageType := '101101'B, nsd := '00'B, cause := ts_ML3_Cause(cause), secondCause := omit, facility := omit, user_user := omit, ss_VersionIndicator := omit } } } } template (value) PDU_ML3_MS_NW ts_ML3_MO_CC_REL_COMPL(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := '0'B, tIExtension := omit } }, msgs := { cc := { releaseComplete_MS_NW := { messageType := '101010'B, nsd := '00'B, cause := omit, facility := omit, user_user := omit, ss_VersionIndicator := omit } } } } template PDU_ML3_NW_MS tr_ML3_MT_CC_REL_COMPL(integer tid) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ?, tIExtension := omit } }, msgs := { cc := { releaseComplete_NW_MS := { messageType := '101010'B, nsd := '00'B, cause := *, facility := *, user_user := * } } } } template PDU_ML3_NW_MS tr_ML3_MT_MM_AUTH_REQ(template OCT16 rand := ?) := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { authenticationRequest := { messageType := '010010'B, nsd := '00'B, cipheringKeySequenceNumber := ?, spare2_4 := ?, authenticationParRAND := rand, authenticationParAUTN := * } } } } template (value) PDU_ML3_MS_NW ts_ML3_MT_MM_AUTH_RESP_2G(OCT4 sres) := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { authenticationResponse := { messageType := '010100'B, nsd := '00'B, authenticationParSRES := sres, authenticationParSRESext := omit } } } } template (value) PDU_ML3_MS_NW ts_ML3_MT_MM_AUTH_RESP_3G(OCT4 sres, octetstring res) := { discriminator := '0101'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { mm := { authenticationResponse := { messageType := '010100'B, nsd := '00'B, authenticationParSRES := sres, authenticationParSRESext := { elementIdentifier := '21'O, lengthIndicator := 0, /* overwritten */ valueField := res } } } } } template PDU_ML3_MS_NW ts_ML3_MO_CC_CALL_CONF(integer tid, template BearerCapability_TLV bcap := omit) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_REPL, /* response from destination */ tIExtension := omit } }, msgs := { cc := { callConfirmed := { messageType := '001000'B, nsd := '00'B, repeatIndicator := omit, bearerCapability1 := bcap, bearerCapability2 := omit, cause := omit, cC_Capabilities := omit, streamIdentifier := omit, supportedCodecs := omit } } } } template PDU_ML3_NW_MS tr_ML3_MT_CC_SETUP(integer tid, template hexstring called := *, template hexstring calling := *, template BearerCapability_TLV bcap := *) := { discriminator := '0011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := c_TIF_ORIG, /* from originator */ tIExtension := omit } }, msgs := { cc := { setup_NW_MS := { messageType := '000101'B, nsd := '00'B, bcRepeatIndicator := *, bearerCapability1 := bcap, bearerCapability2 := *, facility := *, progressIndicator := *, signal := *, callingPartyBCD_Number := tr_Calling(calling) ifpresent, callingPartySubAddress := *, calledPartyBCD_Number := tr_Called(called) ifpresent, calledPartySubAddress := *, redirectingPartyBCDNumber := *, redirectingPartySubaddress := *, llc_RepeatIndicator := *, lowLayerCompatibility1 := *, lowLayerCompatibility2 := *, hlc_RepeatIndicator := *, highLayerCompatibility1 := *, highLayerCompatibility2 := *, user_user := *, priority := *, alert := *, networkCCCapabilities := *, causeofNoCli := *, backupBearerCapacity := * } } } } /*********************************************************************** * Supplementary Services ***********************************************************************/ private template (value) Facility_TLV ts_FacTLV(OCTN facility) := { elementIdentifier := '1C'O, lengthIndicator := lengthof(facility), facilityInformation := facility } private template Facility_TLV tr_FacTLV(template OCTN facility) := { elementIdentifier := '1C'O, lengthIndicator := ?, facilityInformation := facility } private template (value) Facility_LV ts_FacLV(OCTN facility) := { lengthIndicator := lengthof(facility), facilityInformation := facility } private template Facility_LV tr_FacLV(template OCTN facility) := { lengthIndicator := ?, facilityInformation := facility } private function f_facility_or_omit(template (omit) OCTN facility) return template (omit) Facility_TLV { if (istemplatekind(facility, "omit")) { return omit; } else { return ts_FacTLV(valueof(facility)); } } private function f_facility_or_wc(template OCTN facility) return template Facility_TLV { if (istemplatekind(facility, "*")) { return *; } else if (istemplatekind(facility, "?")) { return ?; } else if (istemplatekind(facility, "omit")) { return omit; } else { return tr_FacTLV(facility); } } template (value) PDU_ML3_MS_NW ts_ML3_MO_SS_REGISTER( uint3_t tid, BIT1 ti_flag, OCTN facility, template (omit) SS_VersionIndicator ss_ver := omit ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { register := { messageType := '111011'B, nsd := '00'B, facility := ts_FacTLV(facility), ss_version := ss_ver } } } } template PDU_ML3_MS_NW tr_ML3_MO_SS_REGISTER( template uint3_t tid, template BIT1 ti_flag, template OCTN facility, template SS_VersionIndicator ss_ver := omit ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := f_tid_or_wc(tid), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { register := { messageType := '111011'B, nsd := '00'B, facility := tr_FacTLV(facility), ss_version := ss_ver } } } } template (value) PDU_ML3_NW_MS ts_ML3_MT_SS_REGISTER( uint3_t tid, BIT1 ti_flag, OCTN facility ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { register := { messageType := '111011'B, nsd := '00'B, facility := ts_FacTLV(facility) } } } } template PDU_ML3_NW_MS tr_ML3_MT_SS_REGISTER( template uint3_t tid, template BIT1 ti_flag, template OCTN facility ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := f_tid_or_wc(tid), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { register := { messageType := '111011'B, nsd := '00'B, facility := tr_FacTLV(facility) } } } } template (value) PDU_ML3_MS_NW ts_ML3_MO_SS_FACILITY( uint3_t tid, BIT1 ti_flag, OCTN facility ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { facility := { messageType := '111010'B, nsd := '00'B, facility := ts_FacLV(facility) } } } } template PDU_ML3_MS_NW tr_ML3_MO_SS_FACILITY( template uint3_t tid, template BIT1 ti_flag, template OCTN facility ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := f_tid_or_wc(tid), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { facility := { messageType := '111010'B, nsd := '00'B, facility := tr_FacLV(facility) } } } } template (value) PDU_ML3_NW_MS ts_ML3_MT_SS_FACILITY( uint3_t tid, BIT1 ti_flag, OCTN facility ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { facility := { messageType := '111010'B, nsd := '00'B, facility := ts_FacLV(facility) } } } } template PDU_ML3_NW_MS tr_ML3_MT_SS_FACILITY( template uint3_t tid, template BIT1 ti_flag, template OCTN facility ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := f_tid_or_wc(tid), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { facility := { messageType := '111010'B, nsd := '00'B, facility := tr_FacLV(facility) } } } } template (value) PDU_ML3_MS_NW ts_ML3_MO_SS_RELEASE_COMPLETE( uint3_t tid, BIT1 ti_flag, template (omit) ML3_Cause_TLV cause := omit, template (omit) OCTN facility := omit ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { releaseComplete_MS_NW := { messageType := '101010'B, nsd := '00'B, cause := cause, facility := f_facility_or_omit(facility) } } } } template PDU_ML3_MS_NW tr_ML3_MO_SS_RELEASE_COMPLETE( template uint3_t tid, template BIT1 ti_flag, template ML3_Cause_TLV cause := *, template OCTN facility := * ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := f_tid_or_wc(tid), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { releaseComplete_MS_NW := { messageType := '101010'B, nsd := '00'B, cause := cause, facility := f_facility_or_wc(facility) } } } } template (value) PDU_ML3_NW_MS ts_ML3_MT_SS_RELEASE_COMPLETE( uint3_t tid, BIT1 ti_flag, template (omit) ML3_Cause_TLV cause := omit, template (omit) OCTN facility := omit ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { releaseComplete_NW_MS := { messageType := '101010'B, nsd := '00'B, cause := cause, facility := f_facility_or_omit(facility) } } } } template PDU_ML3_NW_MS tr_ML3_MT_SS_RELEASE_COMPLETE( template uint3_t tid, template BIT1 ti_flag, template ML3_Cause_TLV cause := *, template OCTN facility := * ) := { discriminator := '1011'B, tiOrSkip := { transactionId := { tio := f_tid_or_wc(tid), tiFlag := ti_flag, tIExtension := omit } }, msgs := { ss := { releaseComplete_NW_MS := { messageType := '101010'B, nsd := '00'B, cause := cause, facility := f_facility_or_wc(facility) } } } } /*********************************************************************** * GPRS Mobility Management ***********************************************************************/ template (value) MSNetworkCapabilityV ts_GMM_MsNetCapV := { gea1bit := '1'B, smCapabilitiesviaDedicatedChannels := '1'B, smCapabilitiesviaGPRSChannels := '0'B, ucs2Support := '1'B, ssScreeningIndicator := '01'B, solSACapability := omit, revisionLevelIndicatior := omit, pFCFeatureMode := omit, extendedGEAbits := omit, lcsVAcapability := omit, pSInterRATHOtoUTRANIuModeCapability := omit, pSInterRATHOtoEUTRANS1ModeCapability := omit, eMMCombinedProceduresCapability := omit, iSRSupport := omit, sRVCCtoGERANUTRANCapability := omit, ePCCapability := omit, nFCapability := omit, gERANNertworkSharingCapability := omit, spare_octets := omit }; template (value) MSNetworkCapabilityLV ts_GMM_MsNetCapLV := { lengthIndicator := 0, /* overwritten */ msNetworkCapabilityV := ts_GMM_MsNetCapV }; type enumerated GprsAttachType { GPRS_ATT_T_GPRS, GPRS_ATT_T_GPRS_IMSI_COMBINED }; function ts_GMM_AttachType(boolean combined := false, boolean follow_on_pending := false) return AttachTypeV { var AttachTypeV att; if (combined) { att.attachType := '011'B; } else { att.attachType := '001'B; } att.for_l3 := bool2bit(combined); return att; } type enumerated GprsUpdateType { GPRS_UPD_T_RA ('000'B), GPRS_UPD_T_RA_LA_COMBINED ('001'B), GPRS_UPD_T_RA_LA_COMBINED_IMSI_ATT ('010'B), GPRS_UPD_T_PERIODIC ('011'B) }; /* 10.5.5.18 Update Type */ template UpdateTypeV ts_GMM_UpdateType(GprsUpdateType upd_t, boolean combined := false, boolean follow_on_pending := false) := { valueField := int2bit(enum2int(upd_t), 3), for_l3 := bool2bit(combined) } template (value) DRXParameterV ts_DrxParameterV := { splitPGCycleCode := '00'O, /* no DRX */ nonDRXTimer := '000'B, /* no non-DRX mode */ splitOnCCCH := '0'B, /* not supported */ cnSpecificDRXCycleLength := '0000'B /* SI value used */ }; template (value) AccessCapabilitiesStruct ts_AccesssCap := { lengthIndicator := 0, /* overwritten */ accessCapabilities := { rfPowerCapability := '001'B, /* FIXME */ presenceBitA5 := '0'B, a5bits := omit, esind := '1'B, psbit := '0'B, vgcs := '0'B, vbs := '0'B, presenceBitMultislot := '0'B, multislotcap := omit, accessCapAdditionsAfterRel97 := omit }, spare_bits := omit } template (value) MSRACapabilityValuesRecord ts_RaCapRec(BIT4 att) := { mSRACapabilityValues := { mSRACapabilityValuesExclude1111 := { accessTechnType := '0001'B, /* E-GSM */ accessCapabilities := ts_AccesssCap } }, presenceBitMSRACap := '0'B }; template (value) MSRadioAccessCapabilityLV ts_MS_RaCapa := { lengthIndicator := 0, /* overwritten */ msRadioAccessCapabilityV := { ts_RaCapRec('0001'B) /* E-GSM */ } } template (value) PDU_L3_MS_SGSN ts_GMM_ATTACH_REQ(MobileIdentityLV mi_lv, RoutingAreaIdentificationV old_ra, boolean combined := false, boolean follow_on_pending := false, template (omit) MobileStationClassmark2_TLV cm2_tlv, template (omit) MobileStationClassmark3_TLV cm3_tlv ) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { attachRequest := { messageType := '00000000'B, /* overwritten */ msNetworkCapability := ts_GMM_MsNetCapLV, attachType := valueof(ts_GMM_AttachType(combined, follow_on_pending)), gprsCKSN := { '111'B, '0'B }, drxParam := ts_DrxParameterV, mobileIdentity := mi_lv, oldRoutingAreaID := old_ra, msRACap := ts_MS_RaCapa, ptmsiSignature := omit, /* TODO */ reqGPRStimer := omit, tmsiStatus := omit, pC_LCSCapability := omit, mobileStationClassmark2 := cm2_tlv, mobileStationClassmark3 := cm3_tlv, supportedCodecs := omit, uENetworkCapability := omit, additionalMobileIdentity := omit, routingAreaIdentification2 := omit, voiceDomainandUEsUsageSetting := omit, deviceProperties := omit, p_TMSI_Type := omit, mS_NetworkFeatureSupport := omit, oldLocationAreaIdentification := omit, additionalUpdateType := omit, tMSIBasedNRIcontainer := omit, t3324 := omit, t3312_ExtendedValue := omit, extendedDRXParameters := omit } } } } private function tr_MI_TMSI_TLV(template OCT4 tmsi) return template MobileIdentityTLV { if (istemplatekind(tmsi, "*")) { return *; } else if (istemplatekind(tmsi, "?")) { return ?; } else { var template MobileIdentityTLV mi := { elementIdentifier := '0011000'B, spare1 := '0'B, mobileIdentityLV := { lengthIndicator := 4, mobileIdentityV := { typeOfIdentity := '100'B, oddEvenInd_identity := { tmsi_ptmsi := { oddevenIndicator := '1'B, fillerDigit := '1111'B, octets := tmsi } } } } }; return mi; } } template PDU_L3_SGSN_MS tr_GMM_ATTACH_ACCEPT(template BIT3 res := ?, template RoutingAreaIdentificationV ra := ?, template OCT4 ptmsi := *) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { attachAccept := { messageType := '00000010'B, attachResult := { res, ? }, forceToStandby := ?, updateTimer := ?, radioPriority := ?, radioPriorityTOM8 := ?, routingAreaIdentification := ra, ptmsiSignature := *, readyTimer := *, allocatedPTMSI := tr_MI_TMSI_TLV(ptmsi), msIdentity := *, gmmCause := *, t3302 := *, cellNotification := *, equivalentPLMNs := *, networkFeatureSupport := *, emergencyNumberList := *, requestedMSInformation := *, t3319 := *, t3323 := *, t3312_ExtendedValue := *, additionalNetworkFeatureSupport := *, t3324 := *, extendedDRXParameters := * } } } } template PDU_L3_SGSN_MS tr_GMM_ATTACH_REJECT(template OCT1 cause) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { attachReject := { messageType := '00000100'B, gmmCause := { causeValue := cause }, t3302 := *, t3346 := * } } } } template (value) PDU_L3_MS_SGSN ts_GMM_ATTACH_COMPL := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { attachComplete := { messageType := '00000000'B, /* overwritten */ interRATHandoverInformation := omit, eUTRANinterRATHandoverInformation := omit } } } } template (value) PDU_L3_MS_SGSN ts_GMM_RAU_REQ(MobileIdentityLV mi_lv, GprsUpdateType upd_type, RoutingAreaIdentificationV old_ra, boolean follow_on_pending := false, template (omit) MobileStationClassmark2_TLV cm2_tlv, template (omit) MobileStationClassmark3_TLV cm3_tlv ) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { routingAreaUpdateRequest := { messageType := '00000000'B, /* overwritten */ updateType := ts_GMM_UpdateType(upd_type, follow_on_pending), gprsCKSN := { '111'B, '0'B }, oldRoutingAreaId := old_ra, msRACap := ts_MS_RaCapa, oldPTMSISignature := omit, /* TODO */ readyTimerValue := omit, drxParameter := omit, tmsiStatus := omit, ptmsi := omit, mSNetworkCapability := omit, pdpContextStatus := omit, /* TODO */ pC_LCSCapability := omit, mBMS_ContextStatus := omit, uENetworkCapability := omit, additionalMobileIdentity := omit, oldRoutingAreaIdentification2 := omit, mobileStationClassmark2 := cm2_tlv, mobileStationClassmark3 := cm3_tlv, supportedCodecs := omit, voiceDomainUEUsageSetting := omit, p_TMSI_Type := omit, deviceProperties := omit, mS_NetworkFeatureSupport := omit, oldLocationAreaIdentification := omit, additionalUpdateType := omit, tMSIBasedNRIcontainer := omit, t3324 := omit, t3312_ExtendedValue := omit, extendedDRXParameters := omit } } } } template PDU_L3_SGSN_MS tr_GMM_RAU_REJECT(template OCT1 cause := ?) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { routingAreaUpdateReject := { messageType := '00001011'B, gmmCause := { causeValue := cause }, forceToStandby := ?, spare := '0000'B, t3302 := *, t3346 := * } } } } template PDU_L3_SGSN_MS tr_GMM_RAU_ACCEPT(template BIT3 res := ?, template RoutingAreaIdentificationV ra := ?, template OCT4 ptmsi := *) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { routingAreaUpdateAccept := { messageType := '00001001'B, forceToStandby := ?, updateResult := { res, ? }, raUpdateTimer := ?, routingAreaId := ra, ptmsiSignature := *, allocatedPTMSI := tr_MI_TMSI_TLV(ptmsi), msIdentity := *, receiveNPDUNumbers := *, readyTimer := *, gmmCause := *, t3302 := *, cellNotification := *, equivalentPLMNs := *, pdpContextStatus := *, networkFeatureSupport := *, emergencyNumberList := *, mBMS_ContextStatus := *, requestedMSInformation := *, t3319 := *, t3323 := *, t3312_ExtendedValue := *, additionalNetworkFeatureSupport := *, t3324 := *, extendedDRXParameters := * } } } } template (value) PDU_L3_MS_SGSN ts_GMM_RAU_COMPL := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { routingAreaUpdateComplete := { messageType := '00000000'B, /* overwritten */ receiveNPDUNumbers := omit, interRATHandoverInformation := omit, eUTRANinterRATHandoverInformation := omit } } } } template (value) PDU_L3_MS_SGSN ts_GMM_PTMSI_REALL_COMPL := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { p_TMSIReallocationComplete := { messageType := '00000000'B /* overwritten */ } } } } template (value) PDU_L3_MS_SGSN ts_GMM_AUTH_CIPH_COMPL(ACReferenceNumberV ref, OCT4 res) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { authenticationAndCipheringResponse := { messageType := '00000000'B, /* overwritten */ acReferenceNumber := ref, spare := '0000'B, authenticationParResp := { elementIdentifier := '22'O, valueField := res }, imeisv := omit, authenticationRespParExt := omit } } } } template PDU_L3_SGSN_MS tr_GMM_ID_REQ(template BIT3 id_type := ?) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { identityRequest := { messageType := '00010101'B, identityType := { id_type, '0'B }, forceToStandby := ? } } } } template (value) PDU_L3_MS_SGSN ts_GMM_ID_RESP(MobileIdentityLV mi_lv) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { identityResponse := { messageType := '00000000'B, /* overwritten */ mobileIdentity := mi_lv } } } } template PDU_L3_SGSN_MS tr_GMM_AUTH_REQ(template OCT16 rand := ?, template BIT3 ciph_alg := ?) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { authenticationAndCipheringRequest := { messageType := '00010010'B, cipheringAlgorithm := { ciph_alg, '0'B }, imeisvRequest := ?, forceToStandby := ?, acReferenceNumber := ?, authenticationParameterRAND := { elementIdentifier := '21'O, randValue := rand }, cipheringKeySequenceNumber := *, authenticationParameterAUTN := * } } } } template (value) PDU_L3_MS_SGSN ts_GMM_AUTH_RESP_2G(BIT4 ac_ref, OCT4 sres) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { authenticationAndCipheringResponse := { messageType := '00010011'B, acReferenceNumber := { valueField := ac_ref }, spare := '0000'B, authenticationParResp := { elementIdentifier := '22'O, valueField := sres }, imeisv := omit, authenticationRespParExt := omit } } } } const BIT3 c_GMM_DTT_MO_GPRS := '001'B; const BIT3 c_GMM_DTT_MO_IMSI := '010'B; const BIT3 c_GMM_DTT_MO_GPRS_IMSI_COMBINED := '011'B; const BIT3 c_GMM_DTT_MT_REATTACH_REQUIRED := '001'B; const BIT3 c_GMM_DTT_MT_REATTACH_NOT_REQUIRED := '010'B; const BIT3 c_GMM_DTT_MT_IMSI_DETACH := '011'B; template (value) DetachTypeV ts_GMM_DetType(BIT3 dtt, boolean power_off := false) := { detachType := dtt, powerOffFlag := bool2bit(power_off) } function ts_PtmsiSigTV(template (omit) OCT3 val) return template (omit) P_TMSISignatureTV { var template (omit) P_TMSISignatureTV ret; if (istemplatekind(val, "omit")) { return omit; } else { ret := { elementIdentifier := '19'O, valueField := valueof(val) } return ret; } } function ts_PtmsiSigTLV(template (omit) OCT3 val) return template (omit) P_TMSISignature2TLV { var template (omit) P_TMSISignature2TLV ret; if (istemplatekind(val, "omit")) { return omit; } else { ret := { elementIdentifier := '19'O, lengthIndicator := 3, valueField := valueof(val) } return ret; } } template (value) PDU_L3_MS_SGSN ts_GMM_DET_REQ_MO(BIT3 dtt := c_GMM_DTT_MO_GPRS, boolean power_off := false, template (omit) OCT4 p_tmsi := omit, template (omit) OCT3 p_tmsi_sig := omit) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { detachRequest_MS_SGSN := { messageType := '00000000'B, /* overwritten */ detachType := valueof(ts_GMM_DetType(dtt, power_off)), spare := '0000'B, ptmsi := ts_MI_TMSI_TLV(p_tmsi), ptmsiSignature := ts_PtmsiSigTLV(p_tmsi_sig) } } } } template PDU_L3_SGSN_MS tr_GMM_DET_ACCEPT_MT := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { detachAccept_SGSN_MS := { messageType := '00000110'B, forceToStandby := ?, spare := '0000'B } } } } template PDU_L3_SGSN_MS tr_GMM_DET_REQ_MT( template BIT3 dtt := *, template BIT3 forceToStandby := ?, template OCT1 cause := *) := { discriminator := '1000'B, tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { detachRequest_SGSN_MS := { messageType := '00000101'B, detachType := { dtt, ? }, forceToStandby := { forceToStandby, '0'B }, gmmCause := { elementIdentifier := '25'O, causeValue := { cause } } } } } } template PDU_L3_MS_SGSN ts_GMM_DET_ACCEPT_MO := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { skipIndicator := '0000'B }, msgs := { gprs_mm := { detachAccept_MS_SGSN := { messageType := '00000000'B } } } } function ts_ApnTLV(template (omit) octetstring apn) return template (omit) AccessPointNameTLV { if (istemplatekind(apn, "omit")) { return omit; } else { var template (omit) AccessPointNameTLV ret := { elementIdentifier := '28'O, lengthIndicator := 0, /* overwritten */ accessPointNameValue := apn } return ret; } } function ts_PcoTLV(template (omit) ProtocolConfigOptionsV pco) return template (omit) ProtocolConfigOptionsTLV { if (istemplatekind(pco, "omit")) { return omit; } else { var template (omit) ProtocolConfigOptionsTLV ret := { elementIdentifier := '27'O, lengthIndicator := 0, /* overwritten */ protocolConfigOptionsV := pco } return ret; } } function ts_TearDownIndicatorTV(in template (omit) boolean ind) return template (omit) TearDownIndicatorTV { if (istemplatekind(ind, "omit")) { return omit; } else { var template (omit) TearDownIndicatorTV ret := { tearDownIndicatorV := { tdi_flag := bool2bit(valueof(ind)), spare := '000'B }, elementIdentifier := '1001'B } return ret; } } template (value) PDU_L3_MS_SGSN ts_SM_ACT_PDP_REQ(BIT3 tid, BIT4 nsapi, BIT4 sapi, QoSV qos, PDPAddressV addr, template (omit) octetstring apn := omit, template (omit) ProtocolConfigOptionsV pco := omit ) := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { gprs_sm := { activatePDPContextRequest := { messageType := '00000000'B, /* overwritten */ requestedNSAPI := { nsapi, '0000'B }, requestedLLCSAPI := { sapi, '0000'B }, requestedQoS := { lengthIndicator := 0, /* overwritten */ qoSV := qos }, requestedPDPaddress := { lengthIndicator := 0, /* overwritten */ pdpAddressV := addr }, accessPointName := ts_ApnTLV(apn), protocolConfigOpts := ts_PcoTLV(pco), requestType := omit, deviceProperties := omit, nBIFOM_Container := omit } } } } template PDU_L3_SGSN_MS tr_SM_ACT_PDP_REJ(template BIT3 tid := ?, template OCT1 cause := ?) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { gprs_sm := { activatePDPContextReject := { messageType := '01000011'B, smCause := cause, protocolConfigOpts := *, backOffTimer := *, reAttemptIndicator := *, nBIFOM_Container := * } } } } template PDU_L3_SGSN_MS tr_SM_ACT_PDP_ACCEPT(template BIT3 tid := ?, template BIT4 sapi := ?, template QoSV qos := ?) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { gprs_sm := { activatePDPContextAccept := { messageType := '01000010'B, negotiatedLLCSAPI := { sapi, '0000'B }, negotiatedQoS := { lengthIndicator := ?, qoSV := qos }, radioPriority := ?, spare := '0000'B, pdpAddress := *, protocolConfigOpts := *, packetFlowID := *, sMCause2 := *, connectivityType := *, wLANOffloadIndication := *, nBIFOM_Container := * } } } } template (value) PDU_L3_MS_SGSN ts_SM_DEACT_PDP_REQ_MO(BIT3 tid, OCT1 cause, template (omit) boolean tdown := omit, template (omit) ProtocolConfigOptionsV pco := omit ) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { gprs_sm := { deactivatePDPContextRequest := { messageType := '01000110'B, smCause := cause, tearDownIndicator := ts_TearDownIndicatorTV(tdown), protocolConfigOpts := ts_PcoTLV(pco), mBMSprotocolConfigOptions := omit, t3396 := omit, wLANOffloadIndication := omit, nBIFOM_Container := omit } } } } template (value) PDU_L3_SGSN_MS ts_SM_DEACT_PDP_REQ_MT(BIT3 tid, OCT1 cause, template (omit) boolean tdown := omit, template (omit) ProtocolConfigOptionsV pco := omit ) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { gprs_sm := { deactivatePDPContextRequest := { messageType := '01000110'B, smCause := cause, tearDownIndicator := ts_TearDownIndicatorTV(tdown), protocolConfigOpts := ts_PcoTLV(pco), mBMSprotocolConfigOptions := omit, t3396 := omit, wLANOffloadIndication := omit, nBIFOM_Container := omit } } } } template PDU_L3_SGSN_MS tr_SM_DEACT_PDP_REQ_MT(template BIT3 tid, template OCT1 cause, template (omit) boolean tdown := omit, template (omit) ProtocolConfigOptionsV pco := omit ) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { gprs_sm := { deactivatePDPContextRequest := { messageType := '01000110'B, smCause := cause, tearDownIndicator := ts_TearDownIndicatorTV(tdown), protocolConfigOpts := ts_PcoTLV(pco), mBMSprotocolConfigOptions := *, t3396 := *, wLANOffloadIndication := *, nBIFOM_Container := * } } } } template PDU_L3_SGSN_MS tr_SM_DEACT_PDP_ACCEPT_MT(template BIT3 tid := ?) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_REPL, tIExtension := omit } }, msgs := { gprs_sm := { deactivatePDPContextAccept := { messageType := '01000111'B, protocolConfigOpts := *, mBMSprotocolConfigOptions := *, nBIFOM_Container := * } } } } template PDU_L3_MS_SGSN tr_SM_DEACT_PDP_ACCEPT_MO(template BIT3 tid := ?) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { gprs_sm := { deactivatePDPContextAccept := { messageType := '01000111'B, protocolConfigOpts := *, mBMSprotocolConfigOptions := *, nBIFOM_Container := * } } } } template (value) PDU_L3_MS_SGSN ts_SM_DEACT_PDP_ACCEPT_MO(BIT3 tid) := { discriminator := '1010'B, tiOrSkip := { transactionId := { tio := tid, tiFlag := c_TIF_ORIG, tIExtension := omit } }, msgs := { gprs_sm := { deactivatePDPContextAccept := { messageType := '01000111'B, protocolConfigOpts := omit, mBMSprotocolConfigOptions := omit, nBIFOM_Container := omit } } } } private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring { var integer suffix_len := tot_len - lengthof(prefix); var charstring suffix_ch := int2str(suffix); var integer pad_len := suffix_len - lengthof(suffix_ch); return prefix & int2hex(0, pad_len) & str2hex(suffix_ch); } function f_gen_imei(integer suffix) return hexstring { return f_concat_pad(15, '49999'H, suffix); } function f_gen_imsi(integer suffix) return hexstring { return f_concat_pad(15, '26242'H, suffix); } function f_gen_msisdn(integer suffix) return hexstring { return f_concat_pad(12, '49123'H, suffix); } external function enc_MobileIdentityLV(in MobileIdentityLV si) return octetstring with { extension "prototype(convert) encode(RAW)" }; /* SMS TPDU Layer */ template (value) TPDU_RP_DATA_MS_SGSN ts_SMS_SUBMIT(OCT1 msg_ref, template (value) TP_DA dst_addr, template (value) OCT1 pid, template (value) OCT1 dcs, integer length_ind, octetstring user_data) := { sMS_SUBMIT := { tP_MTI := '01'B, /* SUBMIT */ tP_RD := '1'B, /* reject duplicates */ tP_VPF := '00'B, /* not present */ tP_SRR := '0'B, /* no status report requested */ tP_UDHI := '0'B, /* no user data header in UD */ tP_RP := '0'B, /* no reply path */ tP_MR := msg_ref, tP_DA := dst_addr, tP_PID := pid, tP_DCS := dcs, tP_VP := omit, tP_UDL_UD := { tP_LengthIndicator := length_ind, tP_UD := user_data } } } template TPDU_RP_DATA_SGSN_MS tr_SMS_DELIVER(template TP_OA src_addr := ?, template octetstring user_data := ?, template OCT1 pid := ?, template OCT1 dcs := ?, template BIT1 mms := ? ) := { sMS_DELIVER := { tP_MTI := '00'B, /* DELIVER */ tP_MMS := mms, /* more messages to send */ tP_LP := ?, /* ?!? */ tP_Spare := '0'B, tP_SRI := '0'B, /* status report indication */ tP_UDHI := '0'B, /* no user data header in UD */ tP_RP := '0'B, /* no reply path */ tP_OA := src_addr, tP_PID := pid, tP_DCS := dcs, tP_SCTS := ?, tP_UDL_UD := { tP_LengthIndicator := ?, tP_UD := user_data } } } /* RP Layer */ private function ts_RpOrig(template (omit) RP_NumberingPlan_and_NumberDigits rp_orig) return RP_OriginatorAddressLV { var RP_OriginatorAddressLV ret; if (istemplatekind(rp_orig, "omit")) { ret := { 0, omit }; } else { ret := { 0, valueof(rp_orig) }; } return ret; } private function ts_RpDst(template (omit) RP_NumberingPlan_and_NumberDigits rp_dst) return RP_DestinationAddressLV { var RP_DestinationAddressLV ret; if (istemplatekind(rp_dst, "omit")) { ret := { 0, omit }; } else { ret := { 0, valueof(rp_dst) }; } return ret; } template (value) RPDU_MS_SGSN ts_RP_DATA_MO(OCT1 msg_ref, template (omit) RP_NumberingPlan_and_NumberDigits rp_orig, template (omit) RP_NumberingPlan_and_NumberDigits rp_dst, template (value) TPDU_RP_DATA_MS_SGSN tpdu) := { rP_DATA_MS_SGSN := { rP_MTI := '000'B, rP_Spare := '00000'B, rP_MessageReference := msg_ref, rP_OriginatorAddress := ts_RpOrig(rp_orig), rP_DestinationAddress := ts_RpDst(rp_dst), rP_User_Data := { rP_LengthIndicator := 0, /* overwritten */ rP_TPDU := tpdu } } } template RPDU_SGSN_MS tr_RP_DATA_MT(template OCT1 msg_ref, template RP_NumberingPlan_and_NumberDigits rp_orig, template RP_NumberingPlan_and_NumberDigits rp_dst, template TPDU_RP_DATA_SGSN_MS tpdu) := { rP_DATA_SGSN_MS := { rP_MTI := '001'B, rP_Spare := '00000'B, rP_MessageReference := msg_ref, rP_OriginatorAddress := { ?, rp_orig }, rP_DestinationAddress := { ?, rp_dst }, rP_User_Data := { rP_LengthIndicator := ?, rP_TPDU := tpdu } } } template (value) RPDU_MS_SGSN ts_RP_ACK_MO(OCT1 msg_ref) := { rP_ACK_MS_SGSN := { rP_MTI := '010'B, rP_Spare := '00000'B, rP_MessageReference := msg_ref, rP_User_Data := omit /* FIXME: report */ } } template RPDU_SGSN_MS tr_RP_ACK_MT(template OCT1 msg_ref) := { rP_ACK_SGSN_MS := { rP_MTI := '011'B, rP_Spare := '00000'B, rP_MessageReference := msg_ref, rP_User_Data := omit /* FIXME: report */ } } template (value) RPDU_MS_SGSN ts_RP_ERROR_MO(OCT1 msg_ref, uint7_t cause) := { rP_ERROR_MS_SGSN := { rP_MTI := '100'B, rP_Spare := '00000'B, rP_Message_Reference := msg_ref, rP_CauseLV := { rP_LengthIndicator := 0, /* overwritten */ rP_CauseV := { causeValue := int2bit(cause, 7), ext := '0'B }, rP_diagnisticField := omit }, rP_User_Data := omit /* FIXME: report */ } } private function f_cause_or_wc(template uint7_t cause) return template BIT7 { if (istemplatekind(cause, "?")) { return ?; } else if (istemplatekind(cause, "*")) { return *; } else { return int2bit(valueof(cause), 7); } } template RPDU_SGSN_MS tr_RP_ERROR_MT(template OCT1 msg_ref, template uint7_t cause) := { rP_ERROR_SGSN_MS := { rP_MTI := '101'B, rP_Spare := '00000'B, rP_Message_Reference := msg_ref, rP_CauseLV := { rP_LengthIndicator := 0, /* overwritten */ rP_CauseV := { causeValue := f_cause_or_wc(cause), ext := '0'B }, rP_diagnisticField := omit }, rP_User_Data := omit /* FIXME: report */ } } template (value) RPDU_MS_SGSN ts_RP_SMMA_MO(OCT1 msg_ref) := { rP_SMMA := { rP_MTI := '110'B, rP_Spare := '00000'B, rP_MessageReference := msg_ref } } /* CP Layer */ template (value) L3_SMS_MS_SGSN ts_CP_DATA_MO(template (value) RPDU_MS_SGSN rpdu) := { cP_DATA := { cP_messageType := '00000001'B, cP_User_Data := { lengthIndicator := 0, /* overwritten */ cP_RPDU := rpdu } } } template (value) L3_SMS_MS_SGSN ts_CP_ACK_MO := { cP_ACK := { cP_messageType := '00000100'B } } template (value) L3_SMS_MS_SGSN ts_CP_ERROR_MO(OCT1 cause) := { cP_ERROR := { cP_messageType := '00010000'B, cP_Cause := { causeValue := cause } } } template L3_SMS_SGSN_MS tr_CP_DATA_MT(template RPDU_SGSN_MS rpdu) := { cP_DATA := { cP_messageType := '00000001'B, cP_User_Data := { lengthIndicator := ?, cP_RPDU := rpdu } } } template L3_SMS_SGSN_MS tr_CP_ACK_MT := { cP_ACK := { cP_messageType := '00000100'B } } template L3_SMS_SGSN_MS tr_CP_ERROR_MT(template OCT1 cause) := { cP_ERROR := { cP_messageType := '00010000'B, cP_Cause := { causeValue := cause } } } /* L3 Wrapper */ template (value) PDU_ML3_MS_NW ts_ML3_MO_SMS(uint3_t tid, BIT1 ti_flag, template (value) L3_SMS_MS_SGSN sms_mo) := { discriminator := '1001'B, tiOrSkip := { transactionId := { tio := int2bit(tid, 3), tiFlag := ti_flag, tIExtension := omit } }, msgs := { sms := sms_mo } } private function f_tid_or_wc(template uint3_t tid) return template BIT3 { var template BIT3 ret; if (istemplatekind(tid, "*")) { return *; } else if (istemplatekind(tid, "?")) { return ?; } else { return int2bit(valueof(tid), 3); } } template PDU_ML3_NW_MS tr_ML3_MT_SMS(template uint3_t tid, template BIT1 ti_flag, template L3_SMS_SGSN_MS sms_mt) := { discriminator := '1001'B, tiOrSkip := { transactionId := { tio := f_tid_or_wc(tid), tiFlag := ti_flag, tIExtension := omit } }, msgs := { sms := sms_mt } } }