pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/35367?usp=email )
Change subject: mme: Implement missing UE attach steps ...................................................................... mme: Implement missing UE attach steps Related: OS#6294 Change-Id: Ib4a69aef40bf9dd17d640f650e459668f8415aaa --- M library/GTPv2_Templates.ttcn M library/NAS_Templates.ttcn M library/s1ap/S1AP_Templates.ttcn M mme/MME_Tests.ttcn 4 files changed, 318 insertions(+), 27 deletions(-) Approvals: Jenkins Builder: Verified daniel: Looks good to me, but someone else must approve pespin: Looks good to me, approved osmith: Looks good to me, but someone else must approve diff --git a/library/GTPv2_Templates.ttcn b/library/GTPv2_Templates.ttcn index 1ccbcb8..c09bca8 100644 --- a/library/GTPv2_Templates.ttcn +++ b/library/GTPv2_Templates.ttcn @@ -1040,6 +1040,65 @@ privateExtension := omit }}); +template (present) PDU_GTPCv2 +tr_GTP2C_ModifyBearerReq(template (present) OCT4 d_teid := ?, + template (present) OCT3 seq := ?) := +tr_PDU_GTP2C(d_teid, seq, { + modifyBearerRequest := { + mEI := *, + userLocationInfo := *, + servingNetwork := *, + rAT_Type := *, + indicationFlags := *, + fullyQualifiedTEID := *, + ambr := *, + delayDownlinkPacketNotificationReq := *, + bearerContextGrouped := *, + recovery := *, + uE_TimeZone := *, + csid := *, + user_CSG_Information := *, + iP_Addr := *, + portNumber := *, + lDN := *, + //maxMBR_APN_AMBR := *, + cNOperatorSelectionEntity := *, + presenceReportingAreaInformation := *, + overloadControlInformationGrouped := *, + servingPLMNRateControl := *, + counter := *, + privateExtension := * + }}); + +template (value) PDU_GTPCv2 +ts_GTP2C_ModifyBearerResp(template (value) OCT4 d_teid, + template (value) OCT3 seq, + template (value) GTP2C_Cause cause, + template (value) uint4_t bearer_id, + template (omit) BearerContextGrouped_List bearerContextGrouped := omit) := +ts_PDU_GTP2C(d_teid, seq, '23'O, { + modifyBearerResponse := { + cause := ts_GTP2C_Cause(cause, '0'B), + mSISDN := omit, + linkedEPS_Bearer_ID := ts_GTP2C_EpsBearerId(bearer_id), + aPN_Restriction := omit, + protocolConfigOptions := omit, + bearerContextGrouped := bearerContextGrouped, + changeReportingAction := omit, + cSG_InformationReportingAction := omit, + heNBInformationReporting := omit, + chargingGatewayName := omit, + chargingGatewayAddress := omit, + csid := omit, + recovery := omit, + lDN := omit, + indicationFlags := omit, + presenceReportingAreaAction := omit, + loadControlInformationGrouped := omit, + overloadControlInformationGrouped := omit, + pDNConnectionChargingID := omit, + privateExtension := omit + }}); template (value) PDU_GTPCv2 ts_GTP2C_DeleteBearerReq(template (value) OCT4 d_teid, diff --git a/library/NAS_Templates.ttcn b/library/NAS_Templates.ttcn index 45f5f8d..70561b3 100644 --- a/library/NAS_Templates.ttcn +++ b/library/NAS_Templates.ttcn @@ -1025,6 +1025,55 @@ } } } +template (present) PDU_NAS_EPS +tr_NAS_ActDefEpsBearCtxReq(template (present) BIT4 bearer_id := ?, + template (present) BIT8 proc_tid := ?, + template (present) EPS_QualityOfServiceV qos := ?, + template (present) octetstring apn := ?, + template (present) BIT3 addr_type := ?, + template (present) octetstring addr_info := ?) := { + protocolDiscriminator := c_EPS_NAS_PD_ESM, + ePS_messages := { + ePS_SessionManagement := { + pDU_NAS_EPS_ActDefEPSBearerContextRequest := { + ePSBearerIdentity := bearer_id, + procedureTransactionIdentifier := proc_tid, + messageType := '11000001'B, + ePS_QoS := { + lengthIndicator := ?, + ePS_QualityOfServiceV := qos + }, + accessPointName := { + lengthIndicator := 0, + accessPointNameValue := apn + }, + pDN_Address := { + lengthIndicator := 0, + typeValue := addr_type, + spare := '00000'B, + addressInformation := addr_info + }, + transactionIdentifier := *, + negotiatedQoS := *, + negotiated_LLC_SAPI := *, + radioPriority := *, + packetFlowID := *, + aPN_AMBR := *, + esmCause := *, + protocolConfigOptions := *, + connectivityType := *, + wLANOffloadIndication := *, + nBIFOMContainer := *, + headerCompressinConfiguration := *, + controlPlaneOnlyIndication := *, + extendedProtocolConfigurationOptions := *, + servingPLMNRateControl := *, + extended_APN_AMBR := *, + extendedQoS := * + } + } + } +} /* 8.3.4 Activate Default EPS Bearer Context Accept */ template (value) PDU_NAS_EPS diff --git a/library/s1ap/S1AP_Templates.ttcn b/library/s1ap/S1AP_Templates.ttcn index 9e75cec..26e1ae1 100644 --- a/library/s1ap/S1AP_Templates.ttcn +++ b/library/s1ap/S1AP_Templates.ttcn @@ -22,7 +22,7 @@ *********************************************************************************/ /********************************************************************************* - * 9.1.8 Management Messages + * 9.1.8 Management Messages *********************************************************************************/ /* 9.1.8.4 S1 SETUP REQUEST */ @@ -578,11 +578,30 @@ } /* 9.1.4.3 INITIAL CONTEXT SETUP RESPONSE */ +template (value) E_RABSetupItemCtxtSURes +ts_S1AP_RABSetupItemCtxtSURes(template (value) E_RAB_ID rab_id := 5, + template (value) TransportLayerAddress tla := '00001010000101110001100000000100'B, + template (value) GTP_TEID gtp_teid := '00000002'O) := { + e_RAB_ID := rab_id, + transportLayerAddress := tla, + gTP_TEID := gtp_teid, + iE_Extensions := omit +} +template (value) E_RABSetupListCtxtSURes +ts_S1AP_RABSetupListCtxtSURes(template (value) E_RABSetupItemCtxtSURes it := ts_S1AP_RABSetupItemCtxtSURes()) := { + { + id := S1AP_Constants.id_E_RABSetupItemCtxtSURes, + criticality := ignore, + value_ := { E_RABSetupItemCtxtSURes := it } + } +} + template (value) S1AP_PDU ts_S1AP_InitialCtxSetupResp(template (value) MME_UE_S1AP_ID mme_id, template (value) ENB_UE_S1AP_ID enb_id, - template (value) E_RABSetupListCtxtSURes rab_setup_items, - template (value) E_RABList rab_items) := { + template (value) E_RABSetupListCtxtSURes rab_setup_items + /*OPTIONAL: template (value) E_RABList rab_items */ + ) := { successfulOutcome := { procedureCode := id_InitialContextSetup, criticality := reject, @@ -598,14 +617,15 @@ criticality := reject, value_ := {ENB_UE_S1AP_ID := enb_id} }, { - id := S1AP_Constants.id_E_RABSetupListBearerSURes, + id := S1AP_Constants.id_E_RABSetupListCtxtSURes, criticality := ignore, value_ := {E_RABSetupListCtxtSURes := rab_setup_items} - }, { + } + /*, { id := S1AP_Constants.id_E_RABFailedToSetupListBearerSURes, criticality := ignore, value_ := {E_RABList := rab_items} - } + }*/ } } } diff --git a/mme/MME_Tests.ttcn b/mme/MME_Tests.ttcn index ce30279..eca6b04 100644 --- a/mme/MME_Tests.ttcn +++ b/mme/MME_Tests.ttcn @@ -13,6 +13,7 @@ import from General_Types all; import from Native_Functions all; import from IPL4asp_Types all; +import from Misc_Helpers all; import from S1AP_Types all; import from S1AP_Templates all; import from S1AP_Emulation all; @@ -63,9 +64,34 @@ SupportedTAs supported_tas } +type record BearerConfig { + /* EPS Bearer ID */ + uint4_t ebi optional, + /* TEI (Data) local side, S11 (SGW) */ + OCT4 s11_teid_local optional, + /* TEI (Data) remote side, S11 (SGW) */ + OCT4 s11_teid_remote optional, + /* TEI (Data) local side, S5c (PGW) */ + OCT4 s5c_teid_local optional, + /* TEI (Data) remote side, S5c (PGW) */ + OCT4 s5c_teid_remote optional +}; + /* parameters of emulated UE */ type record UeParams { - hexstring imsi + hexstring imsi, + charstring ue_ip, + + /* TEI (Control) local side, S11 (SGW) */ + OCT4 s11_teic_local, + /* TEI (Control) remote side, S11 (SGW) */ + OCT4 s11_teic_remote optional, + /* TEI (Control) local side, S5c (PGW) */ + OCT4 s5c_teic_local, + /* TEI (Control) remote side, S5c (PGW) */ + OCT4 s5c_teic_remote optional, + + BearerConfig bearer optional } type component MTC_CT { @@ -168,6 +194,9 @@ integer mp_s11_local_port := 2123; charstring mp_s11_remote_ip := "127.0.0.2"; integer mp_s11_remote_port := 2123; + + /* PGW information announced by SGWC. MME never really interacts with these. */ + charstring mp_s5c_pgw_ip := "1.2.3.4"; } /* send incoming unit data messages (like reset) to global SGsAP_UNIT port */ @@ -246,7 +275,19 @@ } friend function f_init_one_ue(inout UeParams uep, integer imsi_suffix) { uep := { - imsi := f_gen_imsi(imsi_suffix) + imsi := f_gen_imsi(imsi_suffix), + ue_ip := "192.168.123.50", + s11_teic_local := '00000000'O, + s11_teic_remote := omit, + s5c_teic_local := '00000000'O, + s5c_teic_remote := omit, + bearer := { + ebi := omit, + s11_teid_local := omit, + s11_teid_remote := omit, + s5c_teid_local := omit, + s5c_teid_remote := omit + } } } friend function f_init_s1ap(charstring id, integer imsi_suffix) runs on MTC_CT { @@ -561,6 +602,33 @@ } } + +private altstep as_s1ap_handle_IntialCtxSetupReq() runs on ConnHdlr { + var S1AP_PDU rx_msg; + var PDU_NAS_EPS rx_nas; + [] S1AP.receive(tr_S1AP_IntialCtxSetupReq) -> value rx_msg { + var template (omit) MME_UE_S1AP_ID mme_ue_id := f_S1AP_get_MME_UE_S1AP_ID(rx_msg); + var template (omit) ENB_UE_S1AP_ID enb_ue_id := f_S1AP_get_ENB_UE_S1AP_ID(rx_msg); + var template (value) E_RABSetupItemCtxtSURes rab_setup_it; + var template (value) E_RABSetupListCtxtSURes rab_setup_items; + var octetstring esm_enc; + var template (value) PDU_NAS_EPS nas; + + rab_setup_it := ts_S1AP_RABSetupItemCtxtSURes(rab_id := 5, + tla := oct2bit(f_inet_addr(mp_mme_ip)), + gtp_teid := '00000002'O); + rab_setup_items := ts_S1AP_RABSetupListCtxtSURes(rab_setup_it); + S1AP.send(ts_S1AP_InitialCtxSetupResp(valueof(mme_ue_id), valueof(enb_ue_id), rab_setup_items)); + + nas := ts_NAS_ActDefEpsBearCtxAck(int2bit(g_pars.ue_pars.bearer.ebi, 4), '00000000'B, omit); + esm_enc := enc_PDU_NAS_EPS(valueof(nas)); + S1AP.send(ts_NAS_AttachComplete(esm_enc)); + } + [] S1AP.receive(PDU_NAS_EPS:?) -> value rx_nas { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx Unexpected NAS PDU msg: ", rx_nas)); + } +} + /* Exepect AuthInfoReq (AIR) from HSS; respond with AuthInforAnswer (AIA) */ private altstep as_DIA_AuthInfo() runs on ConnHdlr { var PDU_DIAMETER rx_dia; @@ -616,18 +684,95 @@ } } -private function f_TC_attach(ConnHdlrPars pars) runs on ConnHdlr { +private altstep as_GTP2C_CreateSession_success() runs on ConnHdlr { + var PDU_GTPCv2 rx_msg; + var BearerContextIEs rx_bctx_ies; + var template (value) FullyQualifiedTEID s11_fteid_c_ie, s11_fteid_u_ie, s5c_fteid_c_ie, s5c_fteid_u_ie; + var template (value) PDN_AddressAllocation paa; + var template (value) BearerContextIEs bctx_ies; - f_init_handler(pars); - var template (value) EPS_MobileIdentityV mi := ts_NAS_MobileId_IMSI(pars.ue_pars.imsi); + [] GTP2.receive(tr_GTP2C_CreateSessionReq(g_pars.ue_pars.imsi)) -> value rx_msg { + /* Parse TEIC and Bearer EBI and TEID and store it in g_pars */ + g_pars.ue_pars.s11_teic_remote := rx_msg.gtpcv2_pdu.createSessionRequest.fullyQualifiedTEID[0].tEID_GRE_Key; + g_pars.ue_pars.s5c_teic_remote := rx_msg.gtpcv2_pdu.createSessionRequest.fullyQualifiedTEID[1].tEID_GRE_Key; + + rx_bctx_ies := rx_msg.gtpcv2_pdu.createSessionRequest.bearerContextGrouped[0].bearerContextIEs; + g_pars.ue_pars.bearer.ebi := rx_bctx_ies.ePS_Bearer_ID.ePS_Bearer_ID_Value; + + /* allocate + register TEID-C on local side */ + g_pars.ue_pars.s11_teic_local := f_gtp2_allocate_teid(); + g_pars.ue_pars.bearer.s11_teid_local := g_pars.ue_pars.s11_teic_local; + g_pars.ue_pars.s5c_teic_local := f_gtp2_allocate_teid(); + g_pars.ue_pars.bearer.s5c_teid_local := g_pars.ue_pars.s5c_teic_local; + + s11_fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S11_MME_GTPC, g_pars.ue_pars.s11_teic_local, 0, + f_inet_addr(mp_s11_local_ip), omit); + s5c_fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_PGW_GTPC, g_pars.ue_pars.s5c_teic_local, 1, + f_inet_addr(mp_s5c_pgw_ip), omit); + s11_fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S1U_SGW_GTPU, g_pars.ue_pars.bearer.s11_teid_local, 0, + f_inet_addr(mp_s11_local_ip), omit); + s5c_fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_PGW_GTPU, g_pars.ue_pars.bearer.s5c_teid_local, 2, + f_inet_addr(mp_s5c_pgw_ip), omit); + paa := ts_GTP2C_PdnAddrAlloc_v4(f_inet_addr(g_pars.ue_pars.ue_ip)); + bctx_ies := ts_GTP2C_BcContextIE(ebi := g_pars.ue_pars.bearer.ebi, + teid_list := { s11_fteid_u_ie, s5c_fteid_u_ie }, + qos := ts_GTP2C_BearerQos('09'O, 0, 0, 0, 0), + charging_id := ts_GTP2C_ChargingID(g_pars.ue_pars.bearer.s11_teid_local)); + + GTP2.send(ts_GTP2C_CreateSessionResp(g_pars.ue_pars.s11_teic_remote, + rx_msg.sequenceNumber, + { s11_fteid_c_ie, s5c_fteid_c_ie }, + paa, { ts_GTP2C_BcGrouped(bctx_ies) } )); + setverdict(pass); + } + [] GTP2.receive { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unexpected GTPv2/S11 message from MME")); + } +} + +private altstep as_GTP2C_ModifyBearer_success() runs on ConnHdlr { + var PDU_GTPCv2 rx_msg; + var BearerContextIEs rx_bctx_ies; + var template (value) FullyQualifiedTEID s11_fteid_c_ie, s11_fteid_u_ie, s5c_fteid_c_ie, s5c_fteid_u_ie; + var template (value) BearerContextIEs bctx_ies; + + [] GTP2.receive(tr_GTP2C_ModifyBearerReq(g_pars.ue_pars.s11_teic_local)) -> value rx_msg { + + rx_bctx_ies := rx_msg.gtpcv2_pdu.modifyBearerRequest.bearerContextGrouped[0].bearerContextIEs; + + /* TODO: validate the S1-U fullyQualifiedTEID announces the IP address provided by the ENB in InitialCtxSetupResp */ + // rx_bctx_ies.fullyQualifiedTEID[0]. == f_inet_addr(mp_mme_ip) + + /* Update S11 TEID */ + g_pars.ue_pars.bearer.s11_teid_remote := rx_bctx_ies.fullyQualifiedTEID[0].tEID_GRE_Key; + + s11_fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S1U_SGW_GTPU, g_pars.ue_pars.bearer.s11_teid_local, 0, + f_inet_addr(mp_s11_local_ip), omit); + bctx_ies := ts_GTP2C_BcContextIE(ebi := g_pars.ue_pars.bearer.ebi, + teid_list := { s11_fteid_u_ie }, + qos := ts_GTP2C_BearerQos('09'O, 0, 0, 0, 0), + charging_id := ts_GTP2C_ChargingID(g_pars.ue_pars.bearer.s11_teid_local)); + + GTP2.send(ts_GTP2C_ModifyBearerResp(g_pars.ue_pars.s11_teic_remote, + rx_msg.sequenceNumber, + Request_accepted, + g_pars.ue_pars.bearer.ebi, + { ts_GTP2C_BcGrouped(bctx_ies) } )); + setverdict(pass); + } + [] GTP2.receive { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unexpected GTPv2/S11 message from MME")); + } +} + + +private function f_attach() runs on ConnHdlr { + var template (value) EPS_MobileIdentityV mi := ts_NAS_MobileId_IMSI(g_pars.ue_pars.imsi); var template (value) PDU_NAS_EPS nas_esm, nas_emm; timer T := 5.0; -/* - nas_esm := ts_NAS_ActDefEpsBearCtxReq(bearer_id := '0000'B, proc_tid := int2bit(1,8), - qos := c_NAS_defaultQoS, apn := c_NAS_defaultAPN, - addr_type := '000'B, addr_info := ''O); -*/ nas_esm := ts_NAS_PdnConnReq(bearer_id := '0000'B, proc_tid := int2bit(1,8), pdn_type := NAS_PDN_T_IPv4, req_type := '001'B); nas_emm := ts_NAS_AttachRequest(att_type := '000'B, kset_id := '000'B, mobile_id := mi, @@ -652,23 +797,31 @@ } /* We now expect the MME to send a Create Session Request to the SGW-C */ - /* TODO: be more restrictive, fix and use tr_GTP2C_CreateSessionReq */ f_gtp2_register_udmsg('20'O); T.start; alt { - [] GTP2.receive(tr_PDU_GTP2C) { - setverdict(pass); - } - [] GTP2.receive { - setverdict(fail, "unexpected GTPv2/S11 message from MME"); - } - [] T.timeout { - setverdict(fail, "no message from MME"); - } + [] as_GTP2C_CreateSession_success(); + [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); } } - /* TODO: Finish this procedure until Attach Complete */ + T.start; + alt { + [] as_s1ap_handle_IntialCtxSetupReq(); + [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); } + } + /* We now expect the MME to send a Modify Bearer Request to the SGW-C */ + f_gtp2_register_udmsg('22'O); + T.start; + alt { + [] as_GTP2C_ModifyBearer_success(); + [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); } + } +} + +private function f_TC_attach(ConnHdlrPars pars) runs on ConnHdlr { + f_init_handler(pars); + f_attach(); } testcase TC_s1ap_attach() runs on MTC_CT { var charstring id := testcasename(); -- To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/35367?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Change-Id: Ib4a69aef40bf9dd17d640f650e459668f8415aaa Gerrit-Change-Number: 35367 Gerrit-PatchSet: 2 Gerrit-Owner: pespin <pes...@sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillm...@sysmocom.de> Gerrit-Reviewer: dexter <pma...@sysmocom.de> Gerrit-Reviewer: fixeria <vyanits...@sysmocom.de> Gerrit-Reviewer: laforge <lafo...@osmocom.org> Gerrit-Reviewer: osmith <osm...@sysmocom.de> Gerrit-Reviewer: pespin <pes...@sysmocom.de> Gerrit-MessageType: merged