From fc5c9b2af0befbfcf3389b65a43a27cee43d2c5a Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Tue, 9 Mar 2021 14:28:07 +0900 Subject: [PATCH] Try to fix the UE infinite attach (#568) If both Delete-Session-Request/Response and UEContextReleaseCommand/UEContextReleaseComplete are failed at the same time, UE cannot attach to the EPC infinitely. So, I've add the protection code if timer expires when MME does not receive Delete-Session-Response. --- src/amf/context.c | 9 +- src/amf/context.h | 4 +- src/amf/gmm-build.c | 5 +- src/amf/gmm-sm.c | 95 +-- src/mme/emm-build.c | 22 +- src/mme/emm-handler.c | 3 +- src/mme/emm-sm.c | 43 +- src/mme/mme-context.c | 9 +- src/mme/mme-context.h | 4 +- src/mme/mme-gtp-path.c | 11 + tests/attach/guti-test.c | 1143 ++++++++++++++++++++++++++ tests/attach/idle-test.c | 3 + tests/common/context.h | 2 +- tests/common/emm-build.c | 36 +- tests/common/emm-build.h | 1 + tests/common/emm-handler.c | 20 + tests/common/emm-handler.h | 2 + tests/common/nas-path.c | 2 + tests/handover/epc-s1-test.c | 2 + tests/registration/ue-context-test.c | 15 +- 20 files changed, 1313 insertions(+), 118 deletions(-) diff --git a/src/amf/context.c b/src/amf/context.c index e6cc3d522..7078caec5 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -1040,7 +1040,7 @@ ran_ue_t *ran_ue_cycle(ran_ue_t *ran_ue) return ogs_pool_cycle(&ran_ue_pool, ran_ue); } -static int amf_ue_new_guti(amf_ue_t *amf_ue) +void amf_ue_new_guti(amf_ue_t *amf_ue) { if (amf_ue->m_tmsi) { /* AMF has a VALID GUTI @@ -1062,7 +1062,7 @@ static int amf_ue_new_guti(amf_ue_t *amf_ue) ogs_hash_set(self.guti_ue_hash, &amf_ue->guti, sizeof(ogs_nas_5gs_guti_t), amf_ue); - return OGS_OK; + amf_ue->guti_present = true; } amf_ue_t *amf_ue_add(ran_ue_t *ran_ue) @@ -1092,9 +1092,6 @@ amf_ue_t *amf_ue_add(ran_ue_t *ran_ue) amf_ue->nas.access_type = OGS_ACCESS_TYPE_3GPP; amf_ue->abba_len = 2; - /* Create New GUTI */ - amf_ue_new_guti(amf_ue); - /* Add All Timers */ amf_ue->t3513.timer = ogs_timer_add( ogs_app()->timer_mgr, amf_timer_t3513_expire, amf_ue); @@ -1378,8 +1375,6 @@ void amf_ue_set_suci(amf_ue_t *amf_ue, } amf_ue->suci = suci; ogs_hash_set(self.suci_hash, amf_ue->suci, strlen(amf_ue->suci), amf_ue); - - amf_ue->guti_present = 1; } void amf_ue_set_supi(amf_ue_t *amf_ue, char *supi) diff --git a/src/amf/context.h b/src/amf/context.h index dcb601921..a52192943 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -263,7 +263,7 @@ struct amf_ue_s { amf_m_tmsi_t *m_tmsi; ogs_nas_5gs_guti_t guti; - int guti_present; + bool guti_present; /* UE Info */ ogs_guami_t *guami; @@ -601,6 +601,8 @@ ran_ue_t *ran_ue_find(uint32_t index); ran_ue_t *ran_ue_find_by_amf_ue_ngap_id(uint64_t amf_ue_ngap_id); ran_ue_t *ran_ue_cycle(ran_ue_t *ran_ue); +void amf_ue_new_guti(amf_ue_t *amf_ue); + amf_ue_t *amf_ue_add(ran_ue_t *ran_ue); void amf_ue_remove(amf_ue_t *amf_ue); void amf_ue_remove_all(void); diff --git a/src/amf/gmm-build.c b/src/amf/gmm-build.c index cccf45f0d..579ce68d1 100644 --- a/src/amf/gmm-build.c +++ b/src/amf/gmm-build.c @@ -71,9 +71,9 @@ ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue) /* Set GUTI */ ogs_debug("[%s] %s 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]", amf_ue->supi, - amf_ue->guti_present ? "[V]" : "[N]", + amf_ue->guti_present == true ? "[V]" : "[N]", ogs_amf_id_hexdump(&amf_ue->guti.amf_id), amf_ue->guti.m_tmsi); - if (amf_ue->guti_present) { + if (amf_ue->guti_present == true) { registration_accept->presencemask |= OGS_NAS_5GS_REGISTRATION_ACCEPT_5G_GUTI_PRESENT; ogs_nas_5gs_nas_guti_to_mobilty_identity_guti( @@ -82,7 +82,6 @@ ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue) mobile_identity->length = sizeof(mobile_identity_guti); mobile_identity->buffer = &mobile_identity_guti; } - amf_ue->guti_present = 0; /* Set TAI List */ registration_accept->presencemask |= OGS_NAS_5GS_REGISTRATION_ACCEPT_TAI_LIST_PRESENT; diff --git a/src/amf/gmm-sm.c b/src/amf/gmm-sm.c index cac63249a..fa23ea7cf 100644 --- a/src/amf/gmm-sm.c +++ b/src/amf/gmm-sm.c @@ -237,65 +237,6 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e) OGS_FSM_TRAN(s, &gmm_state_authentication); break; -#if 0 - case OGS_NAS_5GS_TRACKING_AREA_UPDATE_REQUEST: - ogs_error("[%s] Tracking area update request", - amf_ue->supi); - rv = gmm_handle_tau_request( - amf_ue, &nas_message->gmm.tracking_area_update_request); - if (rv != OGS_OK) { - ogs_error("gmm_handle_tau_request() failed"); - OGS_FSM_TRAN(s, gmm_state_exception); - break; - } - - if (!AMF_UE_HAVE_SUCI(amf_ue)) { - ogs_warn("TAU request : Unknown UE"); - nas_5gs_send_tau_reject(amf_ue, - GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); - OGS_FSM_TRAN(s, &gmm_state_exception); - break; - } - break; - case AMF_EPS_TYPE_TAU_REQUEST: - procedureCode = e->ngap_code; - - if (!SESSION_CONTEXT_IS_AVAILABLE(amf_ue)) { - ogs_warn("No PDN Connection : UE[%s]", amf_ue->imsi_bcd); - nas_5gs_send_tau_reject(amf_ue, - GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); - OGS_FSM_TRAN(s, gmm_state_exception); - break; - } - - if (!SECURITY_CONTEXT_IS_VALID(amf_ue)) { - amf_s6a_send_air(amf_ue, NULL); - OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_authentication); - break; - } - - if (procedureCode == NGAP_ProcedureCode_id_initialUEMessage) { - ogs_debug(" Iniital UE Message"); - if (amf_ue->nas_5gs.update.active_flag) { - nas_5gs_send_tau_accept(amf_ue, - NGAP_ProcedureCode_id_InitialContextSetup); - } else { - nas_5gs_send_tau_accept(amf_ue, - NGAP_ProcedureCode_id_downlinkNASTransport); - amf_send_release_access_bearer_or_ue_context_release(ran_ue); - } - } else if (procedureCode == NGAP_ProcedureCode_id_uplinkNASTransport) { - ogs_debug(" Uplink NAS Transport"); - nas_5gs_send_tau_accept(amf_ue, - NGAP_ProcedureCode_id_downlinkNASTransport); - } else { - ogs_fatal("Invalid Procedure Code[%d]", (int)procedureCode); - } - break; - case OGS_NAS_5GS_TRACKING_AREA_UPDATE_COMPLETE: - ogs_error("[%s] Tracking area update complete", amf_ue->supi); - break; -#endif case OGS_NAS_5GS_5GMM_STATUS: ogs_warn("[%s] 5GMM STATUS : Cause[%d]", amf_ue->suci, nas_message->gmm.gmm_status.gmm_cause); @@ -327,6 +268,11 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e) amf_ue, &nas_message->gmm.ul_nas_transport); break; + case OGS_NAS_5GS_REGISTRATION_COMPLETE: + ogs_error("[%s] Registration complete in INVALID-STATE", + amf_ue->supi); + break; + default: ogs_error("Unknown message [%d]", nas_message->gmm.h.message_type); } @@ -706,6 +652,9 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e) ogs_kdf_nh_gnb(amf_ue->kamf, amf_ue->kgnb, amf_ue->nh); amf_ue->nhcc = 1; + /* Create New GUTI */ + amf_ue_new_guti(amf_ue); + amf_ue_sbi_discover_and_send(OpenAPI_nf_type_UDM, amf_ue, NULL, amf_nudm_uecm_build_registration); @@ -741,22 +690,14 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e) OGS_FSM_TRAN(s, &gmm_state_authentication); break; + case OGS_NAS_5GS_SERVICE_REQUEST: ogs_info("[%s] Service request", amf_ue->supi); nas_5gs_send_service_reject(amf_ue, - OGS_5GMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED); + OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_FSM_TRAN(s, &gmm_state_exception); break; -#if 0 - case OGS_NAS_5GS_TRACKING_AREA_UPDATE_REQUEST: - ogs_debug("Tracking area update request"); - nas_5gs_send_tau_reject(amf_ue, - GMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED); - OGS_FSM_TRAN(s, &gmm_state_exception); - break; -#endif - case OGS_NAS_5GS_5GMM_STATUS: ogs_warn("[%s] 5GMM STATUS : Cause[%d]", amf_ue->supi, nas_message->gmm.gmm_status.gmm_cause); @@ -921,6 +862,11 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e) break; } +/* + * The usage of guti_present is changed + * This following code should be removed. + */ +#if 0 /* * Issues #553 * @@ -940,6 +886,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e) */ if (amf_ue->guti_present == 0) OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_registered); +#endif /* If nas_5gs_send_service_accept() used, we need change it. */ ogs_assert(amf_ue->nas.message_type == @@ -968,6 +915,9 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e) case OGS_NAS_5GS_REGISTRATION_COMPLETE: ogs_info("[%s] Registration complete", amf_ue->supi); + /* Clear GUTI present */ + amf_ue->guti_present = false; + /* * TS24.501 * 5.4.4.2 Generic UE configuration update procedure initiated @@ -1018,6 +968,13 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e) OGS_FSM_TRAN(s, &gmm_state_authentication); break; + case OGS_NAS_5GS_SERVICE_REQUEST: + ogs_info("[%s] Service request", amf_ue->supi); + nas_5gs_send_service_reject(amf_ue, + OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); + OGS_FSM_TRAN(s, &gmm_state_exception); + break; + case OGS_NAS_5GS_5GMM_STATUS: ogs_warn("[%s] 5GMM STATUS : Cause[%d]", amf_ue->supi, nas_message->gmm.gmm_status.gmm_cause); diff --git a/src/mme/emm-build.c b/src/mme/emm-build.c index 82c28bf7f..e0fa6b5c8 100644 --- a/src/mme/emm-build.c +++ b/src/mme/emm-build.c @@ -78,10 +78,10 @@ ogs_pkbuf_t *emm_build_attach_accept( attach_accept->esm_message_container.length = esmbuf->len; ogs_debug(" %s GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI:[%s]", - mme_ue->guti_present ? "[V]" : "[N]", + mme_ue->guti_present == true ? "[V]" : "[N]", mme_ue->guti.mme_gid, mme_ue->guti.mme_code, mme_ue->guti.m_tmsi, mme_ue->imsi_bcd); - if (mme_ue->guti_present) { + if (mme_ue->guti_present == true) { attach_accept->presencemask |= OGS_NAS_EPS_ATTACH_ACCEPT_GUTI_PRESENT; nas_guti->length = sizeof(ogs_nas_eps_mobile_identity_guti_t); nas_guti->guti.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN; @@ -91,7 +91,6 @@ ogs_pkbuf_t *emm_build_attach_accept( nas_guti->guti.mme_code = mme_ue->guti.mme_code; nas_guti->guti.m_tmsi = mme_ue->guti.m_tmsi; } - mme_ue->guti_present = 0; #if 0 /* Need not to include T3402 */ /* Set T3402 */ @@ -378,6 +377,7 @@ ogs_pkbuf_t *emm_build_tau_accept(mme_ue_t *mme_ue) ogs_nas_eps_message_t message; ogs_nas_eps_tracking_area_update_accept_t *tau_accept = &message.emm.tracking_area_update_accept; + ogs_nas_eps_mobile_identity_t *nas_guti = &tau_accept->guti; int served_tai_index = 0; mme_sess_t *sess = NULL; @@ -409,6 +409,22 @@ ogs_pkbuf_t *emm_build_tau_accept(mme_ue_t *mme_ue) tau_accept->t3412_value.unit = OGS_NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH; tau_accept->t3412_value.value = 9; + ogs_debug(" %s GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI:[%s]", + mme_ue->guti_present == true ? "[V]" : "[N]", + mme_ue->guti.mme_gid, mme_ue->guti.mme_code, + mme_ue->guti.m_tmsi, mme_ue->imsi_bcd); + if (mme_ue->guti_present == true) { + tau_accept->presencemask |= + OGS_NAS_EPS_TRACKING_AREA_UPDATE_ACCEPT_GUTI_PRESENT; + nas_guti->length = sizeof(ogs_nas_eps_mobile_identity_guti_t); + nas_guti->guti.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN; + nas_guti->guti.type = OGS_NAS_EPS_MOBILE_IDENTITY_GUTI; + nas_guti->guti.nas_plmn_id = mme_ue->guti.nas_plmn_id; + nas_guti->guti.mme_gid = mme_ue->guti.mme_gid; + nas_guti->guti.mme_code = mme_ue->guti.mme_code; + nas_guti->guti.m_tmsi = mme_ue->guti.m_tmsi; + } + /* Set TAI */ tau_accept->presencemask |= OGS_NAS_EPS_TRACKING_AREA_UPDATE_ACCEPT_TAI_LIST_PRESENT; diff --git a/src/mme/emm-handler.c b/src/mme/emm-handler.c index ce2ac17b9..f217332ea 100644 --- a/src/mme/emm-handler.c +++ b/src/mme/emm-handler.c @@ -553,8 +553,7 @@ int emm_handle_tau_request(mme_ue_t *mme_ue, ? mme_ue->imsi_bcd : "Unknown"); break; default: - ogs_warn("Not implemented[%d]", - eps_mobile_identity->imsi.type); + ogs_error("Not implemented[%d]", eps_mobile_identity->imsi.type); return OGS_OK; } diff --git a/src/mme/emm-sm.c b/src/mme/emm-sm.c index 3c25c9480..65b23238d 100644 --- a/src/mme/emm-sm.c +++ b/src/mme/emm-sm.c @@ -195,7 +195,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e) break; case OGS_NAS_EPS_ATTACH_REQUEST: - ogs_info("Attach request"); + ogs_warn("[%s] Attach request", mme_ue->imsi_bcd); rv = emm_handle_attach_request( mme_ue, &message->emm.attach_request, e->pkbuf); if (rv != OGS_OK) { @@ -266,13 +266,13 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e) if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) { ogs_warn("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd); - nas_eps_send_service_reject(mme_ue, + nas_eps_send_tau_reject(mme_ue, EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED); OGS_FSM_TRAN(s, &emm_state_exception); break; } - if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { + if (!h.integrity_protected || !SECURITY_CONTEXT_IS_VALID(mme_ue)) { mme_s6a_send_air(mme_ue, NULL); OGS_FSM_TRAN(&mme_ue->sm, &emm_state_authentication); break; @@ -304,6 +304,9 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e) case OGS_NAS_EPS_TRACKING_AREA_UPDATE_COMPLETE: ogs_info("Tracking area update complete"); ogs_info(" IMSI[%s]", mme_ue->imsi_bcd); + + /* Clear GUTI present */ + mme_ue->guti_present = false; break; case OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST: @@ -462,9 +465,8 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e) break; case OGS_NAS_EPS_ATTACH_COMPLETE: - ogs_warn("[%s] should not send Attach-Complete" - " if GUTI is not present in Attach-Accept", - mme_ue->imsi_bcd); + ogs_error("[%s] Attach complete in INVALID-STATE", + mme_ue->imsi_bcd); break; default: @@ -624,7 +626,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e) break; } case OGS_NAS_EPS_ATTACH_REQUEST: - ogs_warn("Attach request[%s]", mme_ue->imsi_bcd); + ogs_warn("[%s] Attach request", mme_ue->imsi_bcd); rv = emm_handle_attach_request( mme_ue, &message->emm.attach_request, e->pkbuf); if (rv != OGS_OK) { @@ -759,12 +761,12 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e) ogs_kdf_nh_enb(mme_ue->kasme, mme_ue->kenb, mme_ue->nh); mme_ue->nhcc = 1; + /* Create New GUTI */ + mme_ue_new_guti(mme_ue); + mme_s6a_send_ulr(mme_ue); if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) { - if (mme_ue->guti_present) - OGS_FSM_TRAN(s, &emm_state_initial_context_setup); - else - OGS_FSM_TRAN(s, &emm_state_registered); + OGS_FSM_TRAN(s, &emm_state_initial_context_setup); } else if (mme_ue->nas_eps.type == MME_EPS_TYPE_SERVICE_REQUEST || mme_ue->nas_eps.type == MME_EPS_TYPE_TAU_REQUEST) { @@ -781,7 +783,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e) OGS_FSM_TRAN(s, &emm_state_exception); break; case OGS_NAS_EPS_ATTACH_REQUEST: - ogs_warn("Attach request[%s]", mme_ue->imsi_bcd); + ogs_warn("[%s] Attach request", mme_ue->imsi_bcd); rv = emm_handle_attach_request( mme_ue, &message->emm.attach_request, e->pkbuf); if (rv != OGS_OK) { @@ -877,6 +879,15 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e) message = e->nas_message; ogs_assert(message); + if (message->emm.h.security_header_type + == OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) { + ogs_debug("Service request"); + nas_eps_send_service_reject(mme_ue, + EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); + OGS_FSM_TRAN(s, &emm_state_exception); + break; + } + switch (message->emm.h.message_type) { case OGS_NAS_EPS_ATTACH_COMPLETE: ogs_info("Attach complete"); @@ -909,13 +920,17 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e) OGS_FSM_TRAN(s, emm_state_exception); break; } + + /* Clear GUTI present */ + mme_ue->guti_present = false; + if (MME_P_TMSI_IS_AVAILABLE(mme_ue)) sgsap_send_tmsi_reallocation_complete(mme_ue); OGS_FSM_TRAN(s, &emm_state_registered); break; case OGS_NAS_EPS_ATTACH_REQUEST: - ogs_warn("Attach request[%s]", mme_ue->imsi_bcd); + ogs_warn("[%s] Attach request", mme_ue->imsi_bcd); rv = emm_handle_attach_request( mme_ue, &message->emm.attach_request, e->pkbuf); if (rv != OGS_OK) { @@ -1005,7 +1020,7 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e) switch (message->emm.h.message_type) { case OGS_NAS_EPS_ATTACH_REQUEST: - ogs_info("Attach request[%s]", mme_ue->imsi_bcd); + ogs_warn("[%s] Attach request", mme_ue->imsi_bcd); rv = emm_handle_attach_request( mme_ue, &message->emm.attach_request, e->pkbuf); if (rv != OGS_OK) { diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index a76dc006a..7f7c9ff06 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -2103,7 +2103,7 @@ enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue) return ogs_pool_cycle(&enb_ue_pool, enb_ue); } -static int mme_ue_new_guti(mme_ue_t *mme_ue) +void mme_ue_new_guti(mme_ue_t *mme_ue) { served_gummei_t *served_gummei = NULL; @@ -2137,7 +2137,7 @@ static int mme_ue_new_guti(mme_ue_t *mme_ue) ogs_hash_set(self.guti_ue_hash, &mme_ue->guti, sizeof(ogs_nas_eps_guti_t), mme_ue); - return OGS_OK; + mme_ue->guti_present = true; } static bool compare_ue_info(mme_sgw_t *node, enb_ue_t *enb_ue) @@ -2199,9 +2199,6 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue) ogs_assert(mme_ue->mme_s11_teid > 0 && mme_ue->mme_s11_teid <= ogs_app()->max.ue); - /* Create New GUTI */ - mme_ue_new_guti(mme_ue); - /* * When used for the first time, if last node is set, * the search is performed from the first SGW in a round-robin manner. @@ -2532,8 +2529,6 @@ int mme_ue_set_imsi(mme_ue_t *mme_ue, char *imsi_bcd) ogs_hash_set(self.imsi_ue_hash, mme_ue->imsi, mme_ue->imsi_len, mme_ue); - mme_ue->guti_present = 1; - return OGS_OK; } diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index 43c057788..ac24185e3 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -323,7 +323,7 @@ struct mme_ue_s { mme_m_tmsi_t *m_tmsi; mme_p_tmsi_t p_tmsi; ogs_nas_eps_guti_t guti; - int guti_present; + bool guti_present; uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */ uint32_t sgw_s11_teid; /* SGW-S11-TEID is received from SGW */ @@ -693,6 +693,8 @@ enb_ue_t *enb_ue_find(uint32_t index); enb_ue_t *enb_ue_find_by_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue); +void mme_ue_new_guti(mme_ue_t *mme_ue); + mme_ue_t *mme_ue_add(enb_ue_t *enb_ue); void mme_ue_remove(mme_ue_t *mme_ue); void mme_ue_remove_all(void); diff --git a/src/mme/mme-gtp-path.c b/src/mme/mme-gtp-path.c index 87e1b6320..0250f22ad 100644 --- a/src/mme/mme-gtp-path.c +++ b/src/mme/mme-gtp-path.c @@ -118,6 +118,17 @@ static void timeout(ogs_gtp_xact_t *xact, void *data) switch (type) { case OGS_GTP_DELETE_SESSION_REQUEST_TYPE: + /* + * If SESSION_CONTEXT_WILL_DELETED(MME_UE) is not cleared, + * The MME cannot send Delete-Session-Request to the SGW-C. + * As such, it could be the infinite loop occurred in EMM state machine. + * + * To prevent this situation, + * force clearing SESSION_CONTEXT_WILL_DELETED variable + * when MME does not receive Delete-Session-Response message from SGW-C. + */ + CLEAR_SESSION_CONTEXT(mme_ue); + enb_ue = enb_ue_cycle(mme_ue->enb_ue); if (enb_ue) { s1ap_send_ue_context_release_command(enb_ue, diff --git a/tests/attach/guti-test.c b/tests/attach/guti-test.c index 940e8264a..71e10c98d 100644 --- a/tests/attach/guti-test.c +++ b/tests/attach/guti-test.c @@ -443,11 +443,1154 @@ static void test1_func(abts_case *tc, void *data) test_ue_remove(test_ue); } +static void test2_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *s1ap; + ogs_socknode_t *gtpu; + ogs_pkbuf_t *emmbuf; + ogs_pkbuf_t *esmbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_s1ap_message_t message; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *bearer = NULL; + + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + + bson_t *doc = NULL; + + /* Setup Test UE & Session Context */ + memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci)); + + mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI; + mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI; + mobile_identity_suci.routing_indicator1 = 0; + mobile_identity_suci.routing_indicator2 = 0xf; + mobile_identity_suci.routing_indicator3 = 0xf; + mobile_identity_suci.routing_indicator4 = 0xf; + mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0x37; + mobile_identity_suci.scheme_output[1] = 0x46; + mobile_identity_suci.scheme_output[2] = 0; + mobile_identity_suci.scheme_output[3] = 0; + mobile_identity_suci.scheme_output[4] = 0x06; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13); + ogs_assert(test_ue); + + test_ue->e_cgi.cell_id = 0x1079baf0; + test_ue->nas.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.value = OGS_NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTACH; + + test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; + test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca"; + + sess = test_sess_add_by_apn(test_ue, "internet"); + ogs_assert(sess); + + /* eNB connects to MME */ + s1ap = tests1ap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, s1ap); + + /* eNB connects to SGW */ + gtpu = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu); + + /* Send S1-Setup Reqeust */ + sendbuf = test_s1ap_build_s1_setup_request( + S1AP_ENB_ID_PR_macroENB_ID, 0x54f64); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive S1-Setup Response */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(NULL, recvbuf); + + /********** Insert Subscriber in Database */ + doc = test_db_new_simple(test_ue); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc)); + + /* Send Attach Request */ + memset(&sess->pdn_connectivity_param, + 0, sizeof(sess->pdn_connectivity_param)); + sess->pdn_connectivity_param.eit = 1; + sess->pdn_connectivity_param.pco = 1; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.drx_parameter = 1; + test_ue->attach_request_param.tmsi_status = 1; + test_ue->attach_request_param.mobile_station_classmark_2 = 1; + test_ue->attach_request_param.additional_update_type = 1; + test_ue->attach_request_param.ue_usage_setting = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + + memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param)); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + emmbuf = testemm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + test_ue->mobile_identity_imeisv_presence = true; + emmbuf = testemm_build_security_mode_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive ESM Information Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send ESM Information Response */ + esmbuf = testesm_build_esm_information_response(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Capability Info Indication */ + sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial Context Setup Response */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + test_ue->nr_cgi.cell_id = 0x1234502; + bearer = test_bearer_find_by_ue_ebi(test_ue, 5); + ogs_assert(bearer); + esmbuf = testesm_build_activate_default_eps_bearer_context_accept( + bearer, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + emmbuf = testemm_build_attach_complete(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Attach Request - No Integrity */ + sess->pdn_connectivity_param.eit = 1; + sess->pdn_connectivity_param.pco = 1; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.integrity_protected = 0; + test_ue->attach_request_param.guti = 1; + test_ue->attach_request_param.ms_network_feature_support = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + + /* Receive Authentication request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + emmbuf = testemm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + test_ue->mobile_identity_imeisv_presence = true; + emmbuf = testemm_build_security_mode_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive ESM Information Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send ESM Information Response */ + esmbuf = testesm_build_esm_information_response(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Capability Info Indication */ + sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial Context Setup Response */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + test_ue->nr_cgi.cell_id = 0x1234502; + bearer = test_bearer_find_by_ue_ebi(test_ue, 5); + ogs_assert(bearer); + esmbuf = testesm_build_activate_default_eps_bearer_context_accept( + bearer, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + emmbuf = testemm_build_attach_complete(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Attach Request */ + memset(&sess->pdn_connectivity_param, + 0, sizeof(sess->pdn_connectivity_param)); + sess->pdn_connectivity_param.eit = 1; + sess->pdn_connectivity_param.pco = 1; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.integrity_protected = 1; + test_ue->attach_request_param.guti = 1; + test_ue->attach_request_param.last_visited_registered_tai = 1; + test_ue->attach_request_param.drx_parameter = 1; + test_ue->attach_request_param.ms_network_capability = 1; + test_ue->attach_request_param.location_area_identication = 1; + test_ue->attach_request_param.mobile_station_classmark_2 = 1; + test_ue->attach_request_param.mobile_station_classmark_3 = 1; + test_ue->attach_request_param.supported_codecs = 1; + test_ue->attach_request_param.ue_usage_setting = 1; + test_ue->attach_request_param.old_guti_type = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + + memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param)); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + + /* Receive ESM Information Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send ESM Information Response */ + sess->esm_information_param.pco = 1; + esmbuf = testesm_build_esm_information_response(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + bearer = test_bearer_find_by_ue_ebi(test_ue, 5); + ogs_assert(bearer); + esmbuf = testesm_build_activate_default_eps_bearer_context_accept( + bearer, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + emmbuf = testemm_build_attach_complete(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial Context Setup Response */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Context Release Request */ + sendbuf = test_s1ap_build_ue_context_release_request(test_ue, + S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE Context Release Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue)); + + /* eNB disonncect from MME */ + testenb_s1ap_close(s1ap); + + /* eNB disonncect from SGW */ + test_gtpu_close(gtpu); + + test_ue_remove(test_ue); +} + +static void test3_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *s1ap; + ogs_socknode_t *gtpu; + ogs_pkbuf_t *emmbuf; + ogs_pkbuf_t *esmbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_s1ap_message_t message; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *bearer = NULL; + + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + + bson_t *doc = NULL; + + /* Setup Test UE & Session Context */ + memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci)); + + mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI; + mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI; + mobile_identity_suci.routing_indicator1 = 0; + mobile_identity_suci.routing_indicator2 = 0xf; + mobile_identity_suci.routing_indicator3 = 0xf; + mobile_identity_suci.routing_indicator4 = 0xf; + mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0x37; + mobile_identity_suci.scheme_output[1] = 0x46; + mobile_identity_suci.scheme_output[2] = 0; + mobile_identity_suci.scheme_output[3] = 0; + mobile_identity_suci.scheme_output[4] = 0x06; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13); + ogs_assert(test_ue); + + test_ue->e_cgi.cell_id = 0x54f6401; + test_ue->nas.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.value = OGS_NAS_ATTACH_TYPE_EPS_ATTACH; + + test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; + test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca"; + + sess = test_sess_add_by_apn(test_ue, "internet"); + ogs_assert(sess); + + /* eNB connects to MME */ + s1ap = tests1ap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, s1ap); + + /* eNB connects to SGW */ + gtpu = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu); + + /* Send S1-Setup Reqeust */ + sendbuf = test_s1ap_build_s1_setup_request( + S1AP_ENB_ID_PR_macroENB_ID, 0x54f64); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive S1-Setup Response */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(NULL, recvbuf); + + /********** Insert Subscriber in Database */ + doc = test_db_new_simple(test_ue); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc)); + + /* Send Attach Request */ + memset(&sess->pdn_connectivity_param, + 0, sizeof(sess->pdn_connectivity_param)); + sess->pdn_connectivity_param.eit = 1; + sess->pdn_connectivity_param.pco = 1; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.ms_network_feature_support = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + + memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param)); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + emmbuf = testemm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + test_ue->mobile_identity_imeisv_presence = true; + emmbuf = testemm_build_security_mode_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive ESM Information Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send ESM Information Response */ + esmbuf = testesm_build_esm_information_response(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Capability Info Indication */ + sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial Context Setup Response */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + test_ue->nr_cgi.cell_id = 0x1234502; + bearer = test_bearer_find_by_ue_ebi(test_ue, 5); + ogs_assert(bearer); + esmbuf = testesm_build_activate_default_eps_bearer_context_accept( + bearer, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + emmbuf = testemm_build_attach_complete(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send TAU Request */ + memset(&test_ue->tau_request_param, 0, sizeof(test_ue->tau_request_param)); + test_ue->tau_request_param.ue_network_capability = 1; + test_ue->tau_request_param.last_visited_registered_tai = 1; + test_ue->tau_request_param.drx_parameter = 1; + test_ue->tau_request_param.eps_bearer_context_status = 1; + test_ue->tau_request_param.ms_network_capability = 1; + test_ue->tau_request_param.tmsi_status = 1; + test_ue->tau_request_param.mobile_station_classmark_2 = 1; + test_ue->tau_request_param.ue_usage_setting = 1; + test_ue->tau_request_param.device_properties = 1; + emmbuf = testemm_build_tau_request( + test_ue, true, OGS_NAS_EPS_UPDATE_TYPE_TA_UPDATING); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + + /* Receive Authentication Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + emmbuf = testemm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + test_ue->mobile_identity_imeisv_presence = true; + emmbuf = testemm_build_security_mode_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive InitialContextSetupResponse + TAU Accept */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send TAU Complete */ + emmbuf = testemm_build_tau_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send InitialContextSetupResponse */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send TAU Request */ + memset(&test_ue->tau_request_param, 0, sizeof(test_ue->tau_request_param)); + test_ue->tau_request_param.integrity_protected = 1; + test_ue->tau_request_param.ciphered = 1; + test_ue->tau_request_param.ue_network_capability = 1; + test_ue->tau_request_param.last_visited_registered_tai = 1; + test_ue->tau_request_param.drx_parameter = 1; + test_ue->tau_request_param.eps_bearer_context_status = 1; + test_ue->tau_request_param.ms_network_capability = 1; + test_ue->tau_request_param.tmsi_status = 1; + test_ue->tau_request_param.mobile_station_classmark_2 = 1; + test_ue->tau_request_param.ue_usage_setting = 1; + test_ue->tau_request_param.device_properties = 1; + emmbuf = testemm_build_tau_request( + test_ue, true, OGS_NAS_EPS_UPDATE_TYPE_TA_UPDATING); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + + /* Receive InitialContextSetupResponse + TAU Accept */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send InitialContextSetupResponse */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send UE Context Release Request */ + sendbuf = test_s1ap_build_ue_context_release_request(test_ue, + S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE Context Release Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue)); + + /* eNB disonncect from MME */ + testenb_s1ap_close(s1ap); + + /* eNB disonncect from SGW */ + test_gtpu_close(gtpu); + + test_ue_remove(test_ue); +} + +static void test4_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *s1ap; + ogs_socknode_t *gtpu; + ogs_pkbuf_t *emmbuf; + ogs_pkbuf_t *esmbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_s1ap_message_t message; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *bearer = NULL; + + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + + bson_t *doc = NULL; + + /* Setup Test UE & Session Context */ + memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci)); + + mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI; + mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI; + mobile_identity_suci.routing_indicator1 = 0; + mobile_identity_suci.routing_indicator2 = 0xf; + mobile_identity_suci.routing_indicator3 = 0xf; + mobile_identity_suci.routing_indicator4 = 0xf; + mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0x37; + mobile_identity_suci.scheme_output[1] = 0x46; + mobile_identity_suci.scheme_output[2] = 0; + mobile_identity_suci.scheme_output[3] = 0; + mobile_identity_suci.scheme_output[4] = 0x06; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13); + ogs_assert(test_ue); + + test_ue->e_cgi.cell_id = 0x64010; + test_ue->nas.ksi = 0; + test_ue->nas.value = OGS_NAS_ATTACH_TYPE_EPS_ATTACH; + + test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; + test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca"; + + sess = test_sess_add_by_apn(test_ue, "internet"); + ogs_assert(sess); + + /* eNB connects to MME */ + s1ap = tests1ap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, s1ap); + + /* eNB connects to SGW */ + gtpu = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu); + + /* Send S1-Setup Reqeust */ + sendbuf = test_s1ap_build_s1_setup_request( + S1AP_ENB_ID_PR_macroENB_ID, 0x2343d); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive S1-Setup Response */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(NULL, recvbuf); + + /********** Insert Subscriber in Database */ + doc = test_db_new_simple(test_ue); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc)); + + /* Send Attach Request */ + memset(&sess->pdn_connectivity_param, + 0, sizeof(sess->pdn_connectivity_param)); + sess->pdn_connectivity_param.eit_no_required = 1; + sess->pdn_connectivity_param.pco = 1; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.integrity_protected = 1; + test_ue->attach_request_param.guti = 1; + test_ue->attach_request_param.last_visited_registered_tai = 1; + test_ue->attach_request_param.old_guti_type = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + + memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param)); + test_ue->initial_ue_param.gummei_id = 1; + test_ue->initial_ue_param.gummei.mme_gid = 512; + test_ue->initial_ue_param.gummei.mme_code = 1; + test_ue->initial_ue_param.gummei_type = 1; + test_ue->initial_ue_param.gummei.type = S1AP_GUMMEIType_native; + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Identity Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Identity response */ + emmbuf = testemm_build_identity_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + emmbuf = testemm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + test_ue->mobile_identity_imeisv_presence = true; + emmbuf = testemm_build_security_mode_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Capability Info Indication */ + sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Attach Request */ + memset(&sess->pdn_connectivity_param, + 0, sizeof(sess->pdn_connectivity_param)); + sess->pdn_connectivity_param.eit_no_required = 1; + sess->pdn_connectivity_param.pco = 1; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.integrity_protected = 1; + test_ue->attach_request_param.guti = 1; + test_ue->attach_request_param.last_visited_registered_tai = 1; + test_ue->attach_request_param.old_guti_type = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + + memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param)); + test_ue->initial_ue_param.gummei_id = 1; + test_ue->initial_ue_param.gummei.mme_gid = 512; + test_ue->initial_ue_param.gummei.mme_code = 1; + test_ue->initial_ue_param.gummei_type = 1; + test_ue->initial_ue_param.gummei.type = S1AP_GUMMEIType_native; + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + + /* Receive Authentication Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + emmbuf = testemm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + test_ue->mobile_identity_imeisv_presence = true; + emmbuf = testemm_build_security_mode_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Capability Info Indication */ + sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial Context Setup Response */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + test_ue->nr_cgi.cell_id = 0x1234502; + bearer = test_bearer_find_by_ue_ebi(test_ue, 5); + ogs_assert(bearer); + esmbuf = testesm_build_activate_default_eps_bearer_context_accept( + bearer, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + emmbuf = testemm_build_attach_complete(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Attach Request */ + memset(&sess->pdn_connectivity_param, + 0, sizeof(sess->pdn_connectivity_param)); + sess->pdn_connectivity_param.eit = 1; + sess->pdn_connectivity_param.pco = 1; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.integrity_protected = 1; + test_ue->attach_request_param.guti = 1; + test_ue->attach_request_param.last_visited_registered_tai = 1; + test_ue->attach_request_param.drx_parameter = 1; + test_ue->attach_request_param.ms_network_capability = 1; + test_ue->attach_request_param.location_area_identication = 1; + test_ue->attach_request_param.mobile_station_classmark_2 = 1; + test_ue->attach_request_param.mobile_station_classmark_3 = 1; + test_ue->attach_request_param.supported_codecs = 1; + test_ue->attach_request_param.ue_usage_setting = 1; + test_ue->attach_request_param.old_guti_type = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + + memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param)); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + + /* Receive ESM Information Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send ESM Information Response */ + sess->esm_information_param.pco = 1; + esmbuf = testesm_build_esm_information_response(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + bearer = test_bearer_find_by_ue_ebi(test_ue, 5); + ogs_assert(bearer); + esmbuf = testesm_build_activate_default_eps_bearer_context_accept( + bearer, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + emmbuf = testemm_build_attach_complete(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial Context Setup Response */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Context Release Request */ + sendbuf = test_s1ap_build_ue_context_release_request(test_ue, + S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE Context Release Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue)); + + /* eNB disonncect from MME */ + testenb_s1ap_close(s1ap); + + /* eNB disonncect from SGW */ + test_gtpu_close(gtpu); + + test_ue_remove(test_ue); +} + abts_suite *test_guti(abts_suite *suite) { suite = ADD_SUITE(suite) abts_run_test(suite, test1_func, NULL); + abts_run_test(suite, test2_func, NULL); + abts_run_test(suite, test3_func, NULL); + abts_run_test(suite, test4_func, NULL); return suite; } diff --git a/tests/attach/idle-test.c b/tests/attach/idle-test.c index 934d4f5ec..55b9551de 100644 --- a/tests/attach/idle-test.c +++ b/tests/attach/idle-test.c @@ -240,6 +240,7 @@ static void test1_func(abts_case *tc, void *data) /* Send TAU Request */ memset(&test_ue->tau_request_param, 0, sizeof(test_ue->tau_request_param)); + test_ue->tau_request_param.integrity_protected = 1; test_ue->tau_request_param.ciphered = 1; test_ue->tau_request_param.ue_network_capability = 1; test_ue->tau_request_param.last_visited_registered_tai = 1; @@ -287,6 +288,7 @@ static void test1_func(abts_case *tc, void *data) /* Send TAU Request */ memset(&test_ue->tau_request_param, 0, sizeof(test_ue->tau_request_param)); + test_ue->tau_request_param.integrity_protected = 1; test_ue->tau_request_param.ciphered = 1; test_ue->tau_request_param.ue_network_capability = 1; test_ue->tau_request_param.last_visited_registered_tai = 1; @@ -529,6 +531,7 @@ static void test2_func(abts_case *tc, void *data) /* Send TAU Request */ memset(&test_ue->tau_request_param, 0, sizeof(test_ue->tau_request_param)); + test_ue->tau_request_param.integrity_protected = 1; test_ue->tau_request_param.ciphered = 1; test_ue->tau_request_param.ue_network_capability = 1; test_ue->tau_request_param.last_visited_registered_tai = 1; diff --git a/tests/common/context.h b/tests/common/context.h index 58cb3a528..4146da01c 100644 --- a/tests/common/context.h +++ b/tests/common/context.h @@ -189,8 +189,8 @@ typedef struct test_tau_request_param_s { struct { ED8(uint8_t additional_update_type:1;, uint8_t device_properties:1;, + uint8_t integrity_protected:1;, uint8_t ciphered:1;, - uint8_t spare4:1;, uint8_t spare5:1;, uint8_t spare6:1;, uint8_t spare7:1;, diff --git a/tests/common/emm-build.c b/tests/common/emm-build.c index 0f39300c8..ed0deb05e 100644 --- a/tests/common/emm-build.c +++ b/tests/common/emm-build.c @@ -422,6 +422,23 @@ ogs_pkbuf_t *testemm_build_attach_complete( return test_nas_eps_security_encode(test_ue, &message); } +ogs_pkbuf_t *testemm_build_tau_complete(test_ue_t *test_ue) +{ + ogs_nas_eps_message_t message; + + ogs_assert(test_ue); + + memset(&message, 0, sizeof(message)); + message.h.security_header_type = + OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; + message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; + + message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; + message.emm.h.message_type = OGS_NAS_EPS_TRACKING_AREA_UPDATE_COMPLETE; + + return test_nas_eps_security_encode(test_ue, &message); +} + ogs_pkbuf_t *testemm_build_detach_request(test_ue_t *test_ue, bool switch_off) { ogs_nas_eps_message_t message; @@ -556,12 +573,14 @@ ogs_pkbuf_t *testemm_build_tau_request( ogs_assert(test_ue); memset(&message, 0, sizeof(message)); - if (test_ue->tau_request_param.ciphered) { - message.h.security_header_type = - OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; - } else { - message.h.security_header_type = - OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED; + if (test_ue->tau_request_param.integrity_protected) { + if (test_ue->tau_request_param.ciphered) { + message.h.security_header_type = + OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; + } else { + message.h.security_header_type = + OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED; + } } message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; @@ -736,7 +755,10 @@ ogs_pkbuf_t *testemm_build_tau_request( OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_DEVICE_PROPERTIES_PRESENT; } - return test_nas_eps_security_encode(test_ue, &message); + if (test_ue->tau_request_param.integrity_protected) + return test_nas_eps_security_encode(test_ue, &message); + else + return ogs_nas_eps_plain_encode(&message); } ogs_pkbuf_t *testemm_build_emm_status( diff --git a/tests/common/emm-build.h b/tests/common/emm-build.h index c70f92c76..198570881 100644 --- a/tests/common/emm-build.h +++ b/tests/common/emm-build.h @@ -33,6 +33,7 @@ ogs_pkbuf_t *testemm_build_authentication_failure( ogs_pkbuf_t *testemm_build_security_mode_complete(test_ue_t *test_ue); ogs_pkbuf_t *testemm_build_attach_complete( test_ue_t *test_ue, ogs_pkbuf_t *esmbuf); +ogs_pkbuf_t *testemm_build_tau_complete(test_ue_t *test_ue); ogs_pkbuf_t *testemm_build_detach_request(test_ue_t *test_ue, bool switch_off); diff --git a/tests/common/emm-handler.c b/tests/common/emm-handler.c index d2956f571..fd8b98e07 100644 --- a/tests/common/emm-handler.c +++ b/tests/common/emm-handler.c @@ -108,3 +108,23 @@ void testemm_handle_attach_accept(test_ue_t *test_ue, testemm_send_to_esm(test_ue, &attach_accept->esm_message_container); } + +void testemm_handle_tau_accept(test_ue_t *test_ue, + ogs_nas_eps_tracking_area_update_accept_t *tau_accept) +{ + ogs_nas_eps_mobile_identity_t *guti = NULL; + + ogs_assert(test_ue); + ogs_assert(tau_accept); + + guti = &tau_accept->guti; + + if (tau_accept->presencemask & + OGS_NAS_EPS_TRACKING_AREA_UPDATE_ACCEPT_GUTI_PRESENT) { + memcpy(&test_ue->nas_eps_guti.nas_plmn_id, + &guti->guti.nas_plmn_id, OGS_PLMN_ID_LEN); + test_ue->nas_eps_guti.mme_gid = guti->guti.mme_gid; + test_ue->nas_eps_guti.mme_code = guti->guti.mme_code; + test_ue->nas_eps_guti.m_tmsi = guti->guti.m_tmsi; + } +} diff --git a/tests/common/emm-handler.h b/tests/common/emm-handler.h index 7232d4cf4..0d3f4d44a 100644 --- a/tests/common/emm-handler.h +++ b/tests/common/emm-handler.h @@ -32,6 +32,8 @@ void testemm_handle_security_mode_command(test_ue_t *test_ue, ogs_nas_eps_security_mode_command_t *security_mode_command); void testemm_handle_attach_accept(test_ue_t *test_ue, ogs_nas_eps_attach_accept_t *attach_accept); +void testemm_handle_tau_accept(test_ue_t *test_ue, + ogs_nas_eps_tracking_area_update_accept_t *tau_accept); #ifdef __cplusplus } diff --git a/tests/common/nas-path.c b/tests/common/nas-path.c index 7e4bd1a1a..6a76dde9b 100644 --- a/tests/common/nas-path.c +++ b/tests/common/nas-path.c @@ -156,6 +156,8 @@ void testemm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf) case OGS_NAS_EPS_SERVICE_REJECT: break; case OGS_NAS_EPS_TRACKING_AREA_UPDATE_ACCEPT: + testemm_handle_tau_accept(test_ue, + &message.emm.tracking_area_update_accept); break; case OGS_NAS_EPS_EMM_INFORMATION: break; diff --git a/tests/handover/epc-s1-test.c b/tests/handover/epc-s1-test.c index 3f063124a..b01876227 100644 --- a/tests/handover/epc-s1-test.c +++ b/tests/handover/epc-s1-test.c @@ -363,6 +363,8 @@ static void test1_func(abts_case *tc, void *data) /* Send TAU Request */ memset(&test_ue->tau_request_param, 0, sizeof(test_ue->tau_request_param)); + test_ue->tau_request_param.integrity_protected = 1; + test_ue->tau_request_param.ciphered = 1; test_ue->tau_request_param.ue_network_capability = 1; test_ue->tau_request_param.last_visited_registered_tai = 1; test_ue->tau_request_param.drx_parameter = 1; diff --git a/tests/registration/ue-context-test.c b/tests/registration/ue-context-test.c index e6e86bf24..02a30c0c1 100644 --- a/tests/registration/ue-context-test.c +++ b/tests/registration/ue-context-test.c @@ -373,9 +373,18 @@ static void test2_func(abts_case *tc, void *data) rv = testgnb_ngap_send(ngap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); - /* GUTI Not Present - * SKIP Send Registration complete */ - /* SKIP Receive Configuration update command */ + /* Send Registration complete */ + gmmbuf = testgmm_build_registration_complete(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Configuration update command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); /* Send PDU session establishment request */ sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5);