[MME] Race condition between S1AP and S6A

Assume the UE has Attached, the session has been created,
and is in the IDLE state with the UEContextRelease process.

This could result in the following call flow.

1. TAU request without Integrity Protected
2. Authentication request/response
3. Security-mode command/complete

MME can be performed simultaneously by the HSS(S6A) and UE(S1AP).

Update-Location-Request
Service request
Service reject
Delete Session Request
Delete Session Response
Update-Location-Answer
UEContextReleaseCommand for Service reject
TAU reject
UEContextReleaseCommand for TAU reject
UEContextReleaseComplete
UEContextReleaseComplete

MME crashes when UE sends a service request(S1AP) during ULR/ULA(S6A) with HSS,
which has been fixed.
This commit is contained in:
Sukchan Lee 2024-03-16 22:59:36 +09:00
parent a1bd80515b
commit a1a0a8c0a6
19 changed files with 630 additions and 247 deletions

View File

@ -1440,7 +1440,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
amf_ue->explict_de_registered.n1_done = true; amf_ue->explict_de_registered.n1_done = true;
if (amf_ue->explict_de_registered.sbi_done == true) { if (amf_ue->explict_de_registered.sbi_done == true) {
r = ngap_send_ran_ue_context_release_command(amf_ue->ran_ue, r = ngap_send_ran_ue_context_release_command(ran_ue,
NGAP_Cause_PR_misc, NGAP_CauseMisc_om_intervention, NGAP_Cause_PR_misc, NGAP_CauseMisc_om_intervention,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0); NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);

View File

@ -41,13 +41,12 @@ int nas_5gs_send_to_gnb(amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf)
} }
int nas_5gs_send_to_downlink_nas_transport( int nas_5gs_send_to_downlink_nas_transport(
ran_ue_t *ran_ue, amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf) ran_ue_t *ran_ue, ogs_pkbuf_t *pkbuf)
{ {
int rv; int rv;
ogs_pkbuf_t *ngapbuf = NULL; ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(ran_ue_cycle(ran_ue)); ogs_assert(ran_ue_cycle(ran_ue));
ogs_assert(amf_ue_cycle(amf_ue));
ogs_assert(pkbuf); ogs_assert(pkbuf);
ngapbuf = ngap_build_downlink_nas_transport(ran_ue, pkbuf, false, false); ngapbuf = ngap_build_downlink_nas_transport(ran_ue, pkbuf, false, false);
@ -211,7 +210,7 @@ int nas_5gs_send_registration_reject(
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_5gs_send_to_downlink_nas_transport(ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -290,8 +289,7 @@ int nas_5gs_send_service_accept(amf_ue_t *amf_ue)
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
} else { } else {
rv = nas_5gs_send_to_downlink_nas_transport( rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
amf_ue->ran_ue, amf_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
} }
} }
@ -316,7 +314,7 @@ int nas_5gs_send_service_reject(
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_5gs_send_to_downlink_nas_transport(ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -351,8 +349,7 @@ int nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_5gs_send_to_downlink_nas_transport( rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
amf_ue->ran_ue, amf_ue, gmmbuf);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("nas_5gs_send_to_downlink_nas_transport() failed"); ogs_error("nas_5gs_send_to_downlink_nas_transport() failed");
return rv; return rv;
@ -410,8 +407,7 @@ int nas_5gs_send_de_registration_request(
ogs_timer_start(amf_ue->t3522.timer, ogs_timer_start(amf_ue->t3522.timer,
amf_timer_cfg(AMF_TIMER_T3522)->duration); amf_timer_cfg(AMF_TIMER_T3522)->duration);
rv = nas_5gs_send_to_downlink_nas_transport( rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
amf_ue->ran_ue, amf_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -453,8 +449,7 @@ int nas_5gs_send_identity_request(amf_ue_t *amf_ue)
ogs_timer_start(amf_ue->t3570.timer, ogs_timer_start(amf_ue->t3570.timer,
amf_timer_cfg(AMF_TIMER_T3570)->duration); amf_timer_cfg(AMF_TIMER_T3570)->duration);
rv = nas_5gs_send_to_downlink_nas_transport( rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
amf_ue->ran_ue, amf_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -498,7 +493,7 @@ int nas_5gs_send_authentication_request(amf_ue_t *amf_ue)
amf_metrics_inst_global_inc(AMF_METR_GLOB_CTR_AMF_AUTH_REQ); amf_metrics_inst_global_inc(AMF_METR_GLOB_CTR_AMF_AUTH_REQ);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -529,7 +524,7 @@ int nas_5gs_send_authentication_reject(amf_ue_t *amf_ue)
amf_metrics_inst_global_inc(AMF_METR_GLOB_CTR_AMF_AUTH_REJECT); amf_metrics_inst_global_inc(AMF_METR_GLOB_CTR_AMF_AUTH_REJECT);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -571,7 +566,7 @@ int nas_5gs_send_security_mode_command(amf_ue_t *amf_ue)
ogs_timer_start(amf_ue->t3560.timer, ogs_timer_start(amf_ue->t3560.timer,
amf_timer_cfg(AMF_TIMER_T3560)->duration); amf_timer_cfg(AMF_TIMER_T3560)->duration);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -632,7 +627,7 @@ int nas_5gs_send_configuration_update_command(
amf_metrics_inst_global_inc(AMF_METR_GLOB_CTR_MM_CONF_UPDATE); amf_metrics_inst_global_inc(AMF_METR_GLOB_CTR_MM_CONF_UPDATE);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -887,7 +882,7 @@ int nas_5gs_send_gmm_status(amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t cause)
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(amf_ue->ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -1004,7 +999,7 @@ int nas_5gs_send_dl_nas_transport(ran_ue_t *ran_ue, amf_sess_t *sess,
ogs_error("gmm_build_dl_nas_transport() failed"); ogs_error("gmm_build_dl_nas_transport() failed");
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_5gs_send_to_downlink_nas_transport(ran_ue, amf_ue, gmmbuf); rv = nas_5gs_send_to_downlink_nas_transport(ran_ue, gmmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;

View File

@ -30,7 +30,7 @@ extern "C" {
int nas_5gs_send_to_gnb(amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf); int nas_5gs_send_to_gnb(amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf);
int nas_5gs_send_to_downlink_nas_transport( int nas_5gs_send_to_downlink_nas_transport(
ran_ue_t *ran_ue, amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf); ran_ue_t *ran_ue, ogs_pkbuf_t *pkbuf);
int nas_5gs_send_registration_accept(amf_ue_t *amf_ue); int nas_5gs_send_registration_accept(amf_ue_t *amf_ue);
int nas_5gs_send_registration_reject( int nas_5gs_send_registration_reject(

View File

@ -63,7 +63,7 @@ int emm_handle_attach_request(mme_ue_t *mme_ue,
ogs_assert(esm_message_container); ogs_assert(esm_message_container);
if (!esm_message_container->length) { if (!esm_message_container->length) {
ogs_error("No ESM Message Container"); ogs_error("No ESM Message Container");
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE, OGS_NAS_EMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -143,7 +143,7 @@ int emm_handle_attach_request(mme_ue_t *mme_ue,
/* Send Attach Reject */ /* Send Attach Reject */
ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]", ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac); ogs_plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED, OGS_NAS_EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -187,7 +187,7 @@ int emm_handle_attach_request(mme_ue_t *mme_ue,
"but Integrity[0x%x] cannot be bypassed with EIA0", "but Integrity[0x%x] cannot be bypassed with EIA0",
mme_selected_enc_algorithm(mme_ue), mme_selected_enc_algorithm(mme_ue),
mme_selected_int_algorithm(mme_ue)); mme_selected_int_algorithm(mme_ue));
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH, OGS_NAS_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -210,7 +210,7 @@ int emm_handle_attach_request(mme_ue_t *mme_ue,
emm_cause = emm_cause_from_access_control(mme_ue); emm_cause = emm_cause_from_access_control(mme_ue);
if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) {
ogs_error("Rejected by PLMN-ID access control"); ogs_error("Rejected by PLMN-ID access control");
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -358,7 +358,7 @@ int emm_handle_attach_complete(
return OGS_ERROR; return OGS_ERROR;
} }
r = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); r = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -391,7 +391,7 @@ int emm_handle_identity_response(
ogs_error("mobile_identity length (%d != %d)", ogs_error("mobile_identity length (%d != %d)",
(int)sizeof(ogs_nas_mobile_identity_imsi_t), (int)sizeof(ogs_nas_mobile_identity_imsi_t),
mobile_identity->length); mobile_identity->length);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE, OGS_NAS_EMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -404,7 +404,7 @@ int emm_handle_identity_response(
emm_cause = emm_cause_from_access_control(mme_ue); emm_cause = emm_cause_from_access_control(mme_ue);
if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) {
ogs_error("Rejected by PLMN-ID access control"); ogs_error("Rejected by PLMN-ID access control");
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -417,7 +417,7 @@ int emm_handle_identity_response(
if (mme_ue->imsi_len != OGS_MAX_IMSI_LEN) { if (mme_ue->imsi_len != OGS_MAX_IMSI_LEN) {
ogs_error("Invalid IMSI LEN[%d]", mme_ue->imsi_len); ogs_error("Invalid IMSI LEN[%d]", mme_ue->imsi_len);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE, OGS_NAS_EMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -656,8 +656,8 @@ int emm_handle_tau_request(mme_ue_t *mme_ue,
/* Send TAU reject */ /* Send TAU reject */
ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]", ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac); ogs_plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac);
r = nas_eps_send_tau_reject( r = nas_eps_send_tau_reject(mme_ue->enb_ue, mme_ue,
mme_ue, OGS_NAS_EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED); OGS_NAS_EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
return OGS_ERROR; return OGS_ERROR;
@ -793,8 +793,8 @@ int emm_handle_extended_service_request(mme_ue_t *mme_ue,
/* Send TAU reject */ /* Send TAU reject */
ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]", ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac); ogs_plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac);
r = nas_eps_send_tau_reject( r = nas_eps_send_tau_reject(mme_ue->enb_ue, mme_ue,
mme_ue, OGS_NAS_EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED); OGS_NAS_EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
return OGS_ERROR; return OGS_ERROR;

View File

@ -318,7 +318,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (state != EMM_COMMON_STATE_REGISTERED) { if (state != EMM_COMMON_STATE_REGISTERED) {
ogs_info("Service request : Not registered[%s]", ogs_info("Service request : Not registered[%s]",
mme_ue->imsi_bcd); mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -336,7 +336,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_UE_HAVE_IMSI(mme_ue)) { if (!MME_UE_HAVE_IMSI(mme_ue)) {
ogs_info("Service request : Unknown UE"); ogs_info("Service request : Unknown UE");
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -346,7 +346,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -356,7 +356,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) { if (!SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
ogs_error("No Session Context : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No Session Context : IMSI[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -366,7 +366,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) { if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) {
ogs_error("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED); OGS_NAS_EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -413,7 +413,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_SESSION_RELEASE_PENDING(mme_ue) && if (!MME_SESSION_RELEASE_PENDING(mme_ue) &&
mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) == mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) ==
xact_count) { xact_count) {
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(enb_ue, mme_ue, NULL);
} }
OGS_FSM_TRAN(s, &emm_state_authentication); OGS_FSM_TRAN(s, &emm_state_authentication);
@ -455,7 +455,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
&mme_ue->pdn_connectivity_request); &mme_ue->pdn_connectivity_request);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("nas_eps_send_emm_to_esm() failed"); ogs_error("nas_eps_send_emm_to_esm() failed");
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -474,7 +474,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_SESSION_RELEASE_PENDING(mme_ue) && if (!MME_SESSION_RELEASE_PENDING(mme_ue) &&
mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) == mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) ==
xact_count) { xact_count) {
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(enb_ue, mme_ue, NULL);
} }
OGS_FSM_TRAN(s, &emm_state_authentication); OGS_FSM_TRAN(s, &emm_state_authentication);
@ -502,7 +502,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
ogs_warn("No SGSN route matching RAI[MCC:%u MNC:%u LAC:%u RAC:%u]", ogs_warn("No SGSN route matching RAI[MCC:%u MNC:%u LAC:%u RAC:%u]",
ogs_plmn_id_mcc(&plmn_id), ogs_plmn_id_mnc(&plmn_id), ogs_plmn_id_mcc(&plmn_id), ogs_plmn_id_mnc(&plmn_id),
rai.lai.lac, rai.rac); rai.lai.lac, rai.rac);
r = nas_eps_send_tau_reject(mme_ue, r = nas_eps_send_tau_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -514,7 +514,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_UE_HAVE_IMSI(mme_ue)) { if (!MME_UE_HAVE_IMSI(mme_ue)) {
ogs_info("TAU request : Unknown UE"); ogs_info("TAU request : Unknown UE");
r = nas_eps_send_tau_reject(mme_ue, r = nas_eps_send_tau_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -524,7 +524,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) { if (!SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
ogs_warn("No PDN Connection : UE[%s]", mme_ue->imsi_bcd); ogs_warn("No PDN Connection : UE[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_tau_reject(mme_ue, r = nas_eps_send_tau_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -534,7 +534,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) { if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) {
ogs_warn("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd); ogs_warn("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_tau_reject(mme_ue, r = nas_eps_send_tau_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED); OGS_NAS_EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -543,7 +543,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
} }
if (!h.integrity_protected || !SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!h.integrity_protected || !SECURITY_CONTEXT_IS_VALID(mme_ue)) {
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(enb_ue, mme_ue, NULL);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_authentication); OGS_FSM_TRAN(&mme_ue->sm, &emm_state_authentication);
break; break;
} }
@ -686,7 +686,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_UE_HAVE_IMSI(mme_ue)) { if (!MME_UE_HAVE_IMSI(mme_ue)) {
ogs_warn("Extended Service request : Unknown UE"); ogs_warn("Extended Service request : Unknown UE");
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -696,7 +696,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) { if (!SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
ogs_warn("No PDN Connection : UE[%s]", mme_ue->imsi_bcd); ogs_warn("No PDN Connection : UE[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -706,7 +706,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -726,7 +726,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_P_TMSI_IS_AVAILABLE(mme_ue)) { if (!MME_P_TMSI_IS_AVAILABLE(mme_ue)) {
ogs_warn("No P-TMSI : UE[%s]", mme_ue->imsi_bcd); ogs_warn("No P-TMSI : UE[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -753,7 +753,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
} else { } else {
ogs_warn(" Unknown CSFB Service Type[%d]", ogs_warn(" Unknown CSFB Service Type[%d]",
mme_ue->nas_eps.service.value); mme_ue->nas_eps.service.value);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -771,7 +771,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_P_TMSI_IS_AVAILABLE(mme_ue)) { if (!MME_P_TMSI_IS_AVAILABLE(mme_ue)) {
ogs_warn("No P-TMSI : UE[%s]", mme_ue->imsi_bcd); ogs_warn("No P-TMSI : UE[%s]", mme_ue->imsi_bcd);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -796,7 +796,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
} else { } else {
ogs_warn(" Unknown CSFB Service Type[%d]", ogs_warn(" Unknown CSFB Service Type[%d]",
mme_ue->nas_eps.service.value); mme_ue->nas_eps.service.value);
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -830,7 +830,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!MME_UE_HAVE_IMSI(mme_ue)) { if (!MME_UE_HAVE_IMSI(mme_ue)) {
ogs_warn("Detach request : Unknown UE"); ogs_warn("Detach request : Unknown UE");
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -839,7 +839,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd);
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -924,6 +924,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
{ {
int r, rv; int r, rv;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_nas_eps_message_t *message = NULL; ogs_nas_eps_message_t *message = NULL;
ogs_assert(s); ogs_assert(s);
@ -944,6 +945,9 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
message = e->nas_message; message = e->nas_message;
ogs_assert(message); ogs_assert(message);
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(enb_ue);
switch (message->emm.h.message_type) { switch (message->emm.h.message_type) {
case OGS_NAS_EPS_AUTHENTICATION_RESPONSE: case OGS_NAS_EPS_AUTHENTICATION_RESPONSE:
{ {
@ -1003,7 +1007,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
break; break;
case OGS_NAS_EMM_CAUSE_SYNCH_FAILURE: case OGS_NAS_EMM_CAUSE_SYNCH_FAILURE:
ogs_info("Authentication failure(Synch failure)"); ogs_info("Authentication failure(Synch failure)");
mme_s6a_send_air(mme_ue, mme_s6a_send_air(enb_ue, mme_ue,
authentication_failure_parameter); authentication_failure_parameter);
return; return;
default: default:
@ -1030,7 +1034,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
break; break;
} }
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(enb_ue, mme_ue, NULL);
OGS_FSM_TRAN(s, &emm_state_authentication); OGS_FSM_TRAN(s, &emm_state_authentication);
break; break;
case OGS_NAS_EPS_EMM_STATUS: case OGS_NAS_EPS_EMM_STATUS:
@ -1050,7 +1054,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
if (!MME_UE_HAVE_IMSI(mme_ue)) { if (!MME_UE_HAVE_IMSI(mme_ue)) {
ogs_warn("Detach request : Unknown UE"); ogs_warn("Detach request : Unknown UE");
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -1059,7 +1063,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd);
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -1120,6 +1124,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
{ {
int r, rv; int r, rv;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_nas_eps_message_t *message = NULL; ogs_nas_eps_message_t *message = NULL;
ogs_nas_security_header_type_t h; ogs_nas_security_header_type_t h;
@ -1144,10 +1149,13 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
message = e->nas_message; message = e->nas_message;
ogs_assert(message); ogs_assert(message);
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(enb_ue);
if (message->emm.h.security_header_type if (message->emm.h.security_header_type
== OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) { == OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) {
ogs_debug("Service request"); ogs_debug("Service request");
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED); OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -1207,7 +1215,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
/* Create New GUTI */ /* Create New GUTI */
mme_ue_new_guti(mme_ue); mme_ue_new_guti(mme_ue);
mme_s6a_send_ulr(mme_ue); mme_s6a_send_ulr(enb_ue, mme_ue);
if (mme_ue->next.m_tmsi) { if (mme_ue->next.m_tmsi) {
OGS_FSM_TRAN(s, &emm_state_initial_context_setup); OGS_FSM_TRAN(s, &emm_state_initial_context_setup);
@ -1234,12 +1242,12 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
break; break;
} }
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(enb_ue, mme_ue, NULL);
OGS_FSM_TRAN(s, &emm_state_authentication); OGS_FSM_TRAN(s, &emm_state_authentication);
break; break;
case OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST: case OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST:
ogs_debug("Tracking area update request"); ogs_debug("Tracking area update request");
r = nas_eps_send_tau_reject(mme_ue, r = nas_eps_send_tau_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED); OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -1262,7 +1270,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
if (!MME_UE_HAVE_IMSI(mme_ue)) { if (!MME_UE_HAVE_IMSI(mme_ue)) {
ogs_warn("Detach request : Unknown UE"); ogs_warn("Detach request : Unknown UE");
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -1271,7 +1279,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd);
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -1306,7 +1314,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
"Stop retransmission", mme_ue->imsi_bcd); "Stop retransmission", mme_ue->imsi_bcd);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception); OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED, OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -1334,6 +1342,7 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
{ {
int r, rv, xact_count; int r, rv, xact_count;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_nas_eps_message_t *message = NULL; ogs_nas_eps_message_t *message = NULL;
ogs_nas_security_header_type_t h; ogs_nas_security_header_type_t h;
@ -1354,12 +1363,15 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
message = e->nas_message; message = e->nas_message;
ogs_assert(message); ogs_assert(message);
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(enb_ue);
xact_count = mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR); xact_count = mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR);
if (message->emm.h.security_header_type if (message->emm.h.security_header_type
== OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) { == OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) {
ogs_debug("Service request"); ogs_debug("Service request");
r = nas_eps_send_service_reject(mme_ue, r = nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -1489,7 +1501,7 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
if (!MME_SESSION_RELEASE_PENDING(mme_ue) && if (!MME_SESSION_RELEASE_PENDING(mme_ue) &&
mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) == mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) ==
xact_count) { xact_count) {
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(enb_ue, mme_ue, NULL);
} }
OGS_FSM_TRAN(s, &emm_state_authentication); OGS_FSM_TRAN(s, &emm_state_authentication);
@ -1512,7 +1524,7 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
if (!MME_UE_HAVE_IMSI(mme_ue)) { if (!MME_UE_HAVE_IMSI(mme_ue)) {
ogs_warn("Detach request : Unknown UE"); ogs_warn("Detach request : Unknown UE");
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -1521,7 +1533,7 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd); ogs_error("No Security Context : IMSI[%s]", mme_ue->imsi_bcd);
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
nas_eps_send_service_reject(mme_ue, nas_eps_send_service_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK));
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
break; break;
@ -1580,7 +1592,8 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
ogs_timer_start(mme_ue->t3450.timer, ogs_timer_start(mme_ue->t3450.timer,
mme_timer_cfg(MME_TIMER_T3450)->duration); mme_timer_cfg(MME_TIMER_T3450)->duration);
r = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); r = nas_eps_send_to_downlink_nas_transport(
mme_ue->enb_ue, emmbuf);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
} }
@ -1670,7 +1683,7 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
&mme_ue->pdn_connectivity_request); &mme_ue->pdn_connectivity_request);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("nas_eps_send_emm_to_esm() failed"); ogs_error("nas_eps_send_emm_to_esm() failed");
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -1689,7 +1702,7 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
if (!MME_SESSION_RELEASE_PENDING(mme_ue) && if (!MME_SESSION_RELEASE_PENDING(mme_ue) &&
mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) == mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR) ==
xact_count) { xact_count) {
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(enb_ue, mme_ue, NULL);
} }
OGS_FSM_TRAN(s, &emm_state_authentication); OGS_FSM_TRAN(s, &emm_state_authentication);

View File

@ -143,7 +143,7 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
h.type = e->nas_type; h.type = e->nas_type;
if (h.integrity_protected == 0) { if (h.integrity_protected == 0) {
ogs_error("[%s] No Integrity Protected", mme_ue->imsi_bcd); ogs_error("[%s] No Integrity Protected", mme_ue->imsi_bcd);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED, OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -160,7 +160,7 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) { if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_warn("[%s] No Security Context", mme_ue->imsi_bcd); ogs_warn("[%s] No Security Context", mme_ue->imsi_bcd);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED, OGS_NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);

View File

@ -4275,7 +4275,7 @@ mme_bearer_t *mme_bearer_find_or_add_by_message(
bearer = mme_bearer_find_by_ue_ebi(mme_ue, ebi); bearer = mme_bearer_find_by_ue_ebi(mme_ue, ebi);
if (!bearer) { if (!bearer) {
ogs_error("No Bearer : EBI[%d]", ebi); ogs_error("No Bearer : EBI[%d]", ebi);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -4288,7 +4288,7 @@ mme_bearer_t *mme_bearer_find_or_add_by_message(
if (pti == OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED) { if (pti == OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED) {
ogs_error("Both PTI[%d] and EBI[%d] are 0", pti, ebi); ogs_error("Both PTI[%d] and EBI[%d] are 0", pti, ebi);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -4307,7 +4307,7 @@ mme_bearer_t *mme_bearer_find_or_add_by_message(
if (!bearer) { if (!bearer) {
ogs_error("No Bearer : Linked-EBI[%d]", ogs_error("No Bearer : Linked-EBI[%d]",
linked_eps_bearer_identity->eps_bearer_identity); linked_eps_bearer_identity->eps_bearer_identity);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -4426,7 +4426,7 @@ mme_bearer_t *mme_bearer_find_or_add_by_message(
if (!sess) { if (!sess) {
ogs_error("No Session : ESM message type[%d], PTI[%d]", ogs_error("No Session : ESM message type[%d], PTI[%d]",
message->esm.h.message_type, pti); message->esm.h.message_type, pti);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);

View File

@ -35,6 +35,7 @@ static int mme_s6a_subscription_data_from_avp(struct avp *avp,
struct sess_state { struct sess_state {
mme_ue_t *mme_ue; mme_ue_t *mme_ue;
enb_ue_t *enb_ue;
struct timespec ts; /* Time of sending the message */ struct timespec ts; /* Time of sending the message */
}; };
@ -667,7 +668,7 @@ static int mme_s6a_subscription_data_from_avp(struct avp *avp,
} }
/* MME Sends Authentication Information Request to HSS */ /* MME Sends Authentication Information Request to HSS */
void mme_s6a_send_air(mme_ue_t *mme_ue, void mme_s6a_send_air(enb_ue_t *enb_ue, mme_ue_t *mme_ue,
ogs_nas_authentication_failure_parameter_t ogs_nas_authentication_failure_parameter_t
*authentication_failure_parameter) *authentication_failure_parameter)
{ {
@ -683,7 +684,15 @@ void mme_s6a_send_air(mme_ue_t *mme_ue,
uint8_t resync[OGS_AUTS_LEN + OGS_RAND_LEN]; uint8_t resync[OGS_AUTS_LEN + OGS_RAND_LEN];
ogs_assert(mme_ue); if (!mme_ue_cycle(mme_ue)) {
ogs_error("UE(mme-ue) context has already been removed");
return;
}
if (!enb_ue_cycle(enb_ue)) {
ogs_error("S1 context has already been removed");
return;
}
ogs_debug("[MME] Authentication-Information-Request"); ogs_debug("[MME] Authentication-Information-Request");
@ -695,6 +704,7 @@ void mme_s6a_send_air(mme_ue_t *mme_ue,
ogs_assert(sess_data); ogs_assert(sess_data);
sess_data->mme_ue = mme_ue; sess_data->mme_ue = mme_ue;
sess_data->enb_ue = enb_ue;
/* Create the request */ /* Create the request */
ret = fd_msg_new(ogs_diam_s6a_cmd_air, MSGFL_ALLOC_ETEID, &req); ret = fd_msg_new(ogs_diam_s6a_cmd_air, MSGFL_ALLOC_ETEID, &req);
@ -831,6 +841,7 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
mme_event_t *e = NULL; mme_event_t *e = NULL;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_diam_s6a_message_t *s6a_message = NULL; ogs_diam_s6a_message_t *s6a_message = NULL;
ogs_diam_s6a_aia_message_t *aia_message = NULL; ogs_diam_s6a_aia_message_t *aia_message = NULL;
ogs_diam_e_utran_vector_t *e_utran_vector = NULL; ogs_diam_e_utran_vector_t *e_utran_vector = NULL;
@ -867,6 +878,8 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
mme_ue = sess_data->mme_ue; mme_ue = sess_data->mme_ue;
ogs_assert(mme_ue); ogs_assert(mme_ue);
enb_ue = sess_data->enb_ue;
ogs_assert(enb_ue);
/* Set Authentication-Information Command */ /* Set Authentication-Information Command */
s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t)); s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t));
@ -1022,6 +1035,7 @@ out:
e = mme_event_new(MME_EVENT_S6A_MESSAGE); e = mme_event_new(MME_EVENT_S6A_MESSAGE);
ogs_assert(e); ogs_assert(e);
e->mme_ue = mme_ue; e->mme_ue = mme_ue;
e->enb_ue = enb_ue;
e->s6a_message = s6a_message; e->s6a_message = s6a_message;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
@ -1078,7 +1092,7 @@ out:
} }
/* MME Sends Update Location Request to HSS */ /* MME Sends Update Location Request to HSS */
void mme_s6a_send_ulr(mme_ue_t *mme_ue) void mme_s6a_send_ulr(enb_ue_t *enb_ue, mme_ue_t *mme_ue)
{ {
int ret; int ret;
@ -1089,7 +1103,15 @@ void mme_s6a_send_ulr(mme_ue_t *mme_ue)
struct session *session = NULL; struct session *session = NULL;
ogs_nas_plmn_id_t nas_plmn_id; ogs_nas_plmn_id_t nas_plmn_id;
ogs_assert(mme_ue); if (!mme_ue_cycle(mme_ue)) {
ogs_error("UE(mme-ue) context has already been removed");
return;
}
if (!enb_ue_cycle(enb_ue)) {
ogs_error("S1 context has already been removed");
return;
}
ogs_debug("[MME] Update-Location-Request"); ogs_debug("[MME] Update-Location-Request");
@ -1097,6 +1119,7 @@ void mme_s6a_send_ulr(mme_ue_t *mme_ue)
sess_data = ogs_calloc(1, sizeof(*sess_data)); sess_data = ogs_calloc(1, sizeof(*sess_data));
ogs_assert(sess_data); ogs_assert(sess_data);
sess_data->mme_ue = mme_ue; sess_data->mme_ue = mme_ue;
sess_data->enb_ue = enb_ue;
/* Create the request */ /* Create the request */
ret = fd_msg_new(ogs_diam_s6a_cmd_ulr, MSGFL_ALLOC_ETEID, &req); ret = fd_msg_new(ogs_diam_s6a_cmd_ulr, MSGFL_ALLOC_ETEID, &req);
@ -1234,98 +1257,6 @@ void mme_s6a_send_ulr(mme_ue_t *mme_ue)
ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0); ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0);
} }
/* MME Sends Purge UE Request to HSS */
void mme_s6a_send_pur(mme_ue_t *mme_ue)
{
int ret;
struct msg *req = NULL;
struct avp *avp;
union avp_value val;
struct sess_state *sess_data = NULL, *svg;
struct session *session = NULL;
ogs_assert(mme_ue);
ogs_debug("[MME] Purge-UE-Request");
/* Create the random value to store with the session */
sess_data = ogs_calloc(1, sizeof(*sess_data));
ogs_assert(sess_data);
sess_data->mme_ue = mme_ue;
/* Create the request */
ret = fd_msg_new(ogs_diam_s6a_cmd_pur, MSGFL_ALLOC_ETEID, &req);
ogs_assert(ret == 0);
/* Create a new session */
#define OGS_DIAM_S6A_APP_SID_OPT "app_s6a"
ret = fd_msg_new_session(req, (os0_t)OGS_DIAM_S6A_APP_SID_OPT,
CONSTSTRLEN(OGS_DIAM_S6A_APP_SID_OPT));
ogs_assert(ret == 0);
ret = fd_msg_sess_get(fd_g_config->cnf_dict, req, &session, NULL);
ogs_assert(ret == 0);
/* Set the Auth-Session-State AVP */
ret = fd_msg_avp_new(ogs_diam_auth_session_state, 0, &avp);
ogs_assert(ret == 0);
val.i32 = OGS_DIAM_AUTH_SESSION_NO_STATE_MAINTAINED;
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set Origin-Host & Origin-Realm */
ret = fd_msg_add_origin(req, 0);
ogs_assert(ret == 0);
/* Set the Destination-Realm AVP */
ret = fd_msg_avp_new(ogs_diam_destination_realm, 0, &avp);
ogs_assert(ret == 0);
val.os.data = (unsigned char *)(fd_g_config->cnf_diamrlm);
val.os.len = strlen(fd_g_config->cnf_diamrlm);
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set the User-Name AVP */
ret = fd_msg_avp_new(ogs_diam_user_name, 0, &avp);
ogs_assert(ret == 0);
val.os.data = (uint8_t *)mme_ue->imsi_bcd;
val.os.len = strlen(mme_ue->imsi_bcd);
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set Vendor-Specific-Application-Id AVP */
ret = ogs_diam_message_vendor_specific_appid_set(
req, OGS_DIAM_S6A_APPLICATION_ID);
ogs_assert(ret == 0);
ret = clock_gettime(CLOCK_REALTIME, &sess_data->ts);
ogs_assert(ret == 0);
/* Keep a pointer to the session data for debug purpose,
* in real life we would not need it */
svg = sess_data;
/* Store this value in the session */
ret = fd_sess_state_store(mme_s6a_reg, session, &sess_data);
ogs_assert(ret == 0);
ogs_assert(sess_data == 0);
/* Send the request */
ret = fd_msg_send(&req, mme_s6a_pua_cb, svg);
ogs_assert(ret == 0);
/* Increment the counter */
ogs_assert(pthread_mutex_lock(&ogs_diam_logger_self()->stats_lock) == 0);
ogs_diam_logger_self()->stats.nb_sent++;
ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0);
}
/* MME received Update Location Answer from HSS */ /* MME received Update Location Answer from HSS */
static void mme_s6a_ula_cb(void *data, struct msg **msg) static void mme_s6a_ula_cb(void *data, struct msg **msg)
{ {
@ -1342,6 +1273,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
mme_event_t *e = NULL; mme_event_t *e = NULL;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_diam_s6a_message_t *s6a_message = NULL; ogs_diam_s6a_message_t *s6a_message = NULL;
ogs_diam_s6a_ula_message_t *ula_message = NULL; ogs_diam_s6a_ula_message_t *ula_message = NULL;
ogs_subscription_data_t *subscription_data = NULL; ogs_subscription_data_t *subscription_data = NULL;
@ -1378,6 +1310,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
mme_ue = sess_data->mme_ue; mme_ue = sess_data->mme_ue;
ogs_assert(mme_ue); ogs_assert(mme_ue);
enb_ue = sess_data->enb_ue;
ogs_assert(enb_ue);
/* Set Update-Location Command */ /* Set Update-Location Command */
s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t)); s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t));
@ -1519,6 +1453,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
e = mme_event_new(MME_EVENT_S6A_MESSAGE); e = mme_event_new(MME_EVENT_S6A_MESSAGE);
ogs_assert(e); ogs_assert(e);
e->mme_ue = mme_ue; e->mme_ue = mme_ue;
e->enb_ue = enb_ue;
e->s6a_message = s6a_message; e->s6a_message = s6a_message;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
@ -1579,6 +1514,107 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
return; return;
} }
/* MME Sends Purge UE Request to HSS */
void mme_s6a_send_pur(enb_ue_t *enb_ue, mme_ue_t *mme_ue)
{
int ret;
struct msg *req = NULL;
struct avp *avp;
union avp_value val;
struct sess_state *sess_data = NULL, *svg;
struct session *session = NULL;
if (!mme_ue_cycle(mme_ue)) {
ogs_error("UE(mme-ue) context has already been removed");
return;
}
if (!enb_ue_cycle(enb_ue)) {
ogs_error("S1 context has already been removed");
return;
}
ogs_debug("[MME] Purge-UE-Request");
/* Create the random value to store with the session */
sess_data = ogs_calloc(1, sizeof(*sess_data));
ogs_assert(sess_data);
sess_data->mme_ue = mme_ue;
sess_data->enb_ue = enb_ue;
/* Create the request */
ret = fd_msg_new(ogs_diam_s6a_cmd_pur, MSGFL_ALLOC_ETEID, &req);
ogs_assert(ret == 0);
/* Create a new session */
#define OGS_DIAM_S6A_APP_SID_OPT "app_s6a"
ret = fd_msg_new_session(req, (os0_t)OGS_DIAM_S6A_APP_SID_OPT,
CONSTSTRLEN(OGS_DIAM_S6A_APP_SID_OPT));
ogs_assert(ret == 0);
ret = fd_msg_sess_get(fd_g_config->cnf_dict, req, &session, NULL);
ogs_assert(ret == 0);
/* Set the Auth-Session-State AVP */
ret = fd_msg_avp_new(ogs_diam_auth_session_state, 0, &avp);
ogs_assert(ret == 0);
val.i32 = OGS_DIAM_AUTH_SESSION_NO_STATE_MAINTAINED;
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set Origin-Host & Origin-Realm */
ret = fd_msg_add_origin(req, 0);
ogs_assert(ret == 0);
/* Set the Destination-Realm AVP */
ret = fd_msg_avp_new(ogs_diam_destination_realm, 0, &avp);
ogs_assert(ret == 0);
val.os.data = (unsigned char *)(fd_g_config->cnf_diamrlm);
val.os.len = strlen(fd_g_config->cnf_diamrlm);
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set the User-Name AVP */
ret = fd_msg_avp_new(ogs_diam_user_name, 0, &avp);
ogs_assert(ret == 0);
val.os.data = (uint8_t *)mme_ue->imsi_bcd;
val.os.len = strlen(mme_ue->imsi_bcd);
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Set Vendor-Specific-Application-Id AVP */
ret = ogs_diam_message_vendor_specific_appid_set(
req, OGS_DIAM_S6A_APPLICATION_ID);
ogs_assert(ret == 0);
ret = clock_gettime(CLOCK_REALTIME, &sess_data->ts);
ogs_assert(ret == 0);
/* Keep a pointer to the session data for debug purpose,
* in real life we would not need it */
svg = sess_data;
/* Store this value in the session */
ret = fd_sess_state_store(mme_s6a_reg, session, &sess_data);
ogs_assert(ret == 0);
ogs_assert(sess_data == 0);
/* Send the request */
ret = fd_msg_send(&req, mme_s6a_pua_cb, svg);
ogs_assert(ret == 0);
/* Increment the counter */
ogs_assert(pthread_mutex_lock(&ogs_diam_logger_self()->stats_lock) == 0);
ogs_diam_logger_self()->stats.nb_sent++;
ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0);
}
/* MME received Purge UE Answer from HSS */ /* MME received Purge UE Answer from HSS */
static void mme_s6a_pua_cb(void *data, struct msg **msg) static void mme_s6a_pua_cb(void *data, struct msg **msg)
{ {
@ -1595,6 +1631,7 @@ static void mme_s6a_pua_cb(void *data, struct msg **msg)
mme_event_t *e = NULL; mme_event_t *e = NULL;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_diam_s6a_message_t *s6a_message = NULL; ogs_diam_s6a_message_t *s6a_message = NULL;
ogs_diam_s6a_pua_message_t *pua_message = NULL; ogs_diam_s6a_pua_message_t *pua_message = NULL;
@ -1630,6 +1667,8 @@ static void mme_s6a_pua_cb(void *data, struct msg **msg)
mme_ue = sess_data->mme_ue; mme_ue = sess_data->mme_ue;
ogs_assert(mme_ue); ogs_assert(mme_ue);
enb_ue = sess_data->enb_ue;
ogs_assert(enb_ue);
/* Set Purge-UE Command */ /* Set Purge-UE Command */
s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t)); s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t));
@ -1727,6 +1766,7 @@ static void mme_s6a_pua_cb(void *data, struct msg **msg)
e = mme_event_new(MME_EVENT_S6A_MESSAGE); e = mme_event_new(MME_EVENT_S6A_MESSAGE);
ogs_assert(e); ogs_assert(e);
e->mme_ue = mme_ue; e->mme_ue = mme_ue;
e->enb_ue = enb_ue;
e->s6a_message = s6a_message; e->s6a_message = s6a_message;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {

View File

@ -30,13 +30,13 @@ int mme_fd_init(void);
void mme_fd_final(void); void mme_fd_final(void);
/* MME Sends Authentication Information Request to HSS */ /* MME Sends Authentication Information Request to HSS */
void mme_s6a_send_air(mme_ue_t *mme_ue, void mme_s6a_send_air(enb_ue_t *enb_ue, mme_ue_t *mme_ue,
ogs_nas_authentication_failure_parameter_t ogs_nas_authentication_failure_parameter_t
*authentication_failure_parameter); *authentication_failure_parameter);
/* MME Sends Update Location Request to HSS */ /* MME Sends Update Location Request to HSS */
void mme_s6a_send_ulr(mme_ue_t *mme_ue); void mme_s6a_send_ulr(enb_ue_t *enb_ue, mme_ue_t *mme_ue);
/* MME Sends Purge UE Request to HSS */ /* MME Sends Purge UE Request to HSS */
void mme_s6a_send_pur(mme_ue_t *mme_ue); void mme_s6a_send_pur(enb_ue_t *enb_ue, mme_ue_t *mme_ue);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -344,7 +344,7 @@ int mme_gn_handle_sgsn_context_response(
if (resp->cause.u8 != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) { if (resp->cause.u8 != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) {
ogs_error("[Gn] Rx SGSN Context Response cause:%u", resp->cause.u8); ogs_error("[Gn] Rx SGSN Context Response cause:%u", resp->cause.u8);
rv = nas_eps_send_tau_reject(mme_ue, emm_cause); rv = nas_eps_send_tau_reject(mme_ue->enb_ue, mme_ue, emm_cause);
return OGS_GTP1_CAUSE_SYSTEM_FAILURE; return OGS_GTP1_CAUSE_SYSTEM_FAILURE;
} }
@ -434,7 +434,7 @@ int mme_gn_handle_sgsn_context_response(
nack_and_reject: nack_and_reject:
rv = mme_gtp1_send_sgsn_context_ack(mme_ue, gtp1_cause, xact); rv = mme_gtp1_send_sgsn_context_ack(mme_ue, gtp1_cause, xact);
ogs_info("[%s] TAU Reject [OGS_NAS_EMM_CAUSE:%d]", mme_ue->imsi_bcd, emm_cause); ogs_info("[%s] TAU Reject [OGS_NAS_EMM_CAUSE:%d]", mme_ue->imsi_bcd, emm_cause);
rv = nas_eps_send_tau_reject(mme_ue, emm_cause); rv = nas_eps_send_tau_reject(mme_ue->enb_ue, mme_ue, emm_cause);
return OGS_GTP1_CAUSE_SYSTEM_FAILURE; return OGS_GTP1_CAUSE_SYSTEM_FAILURE;
} }

View File

@ -160,7 +160,7 @@ void mme_s11_handle_create_session_response(
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) { if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
ogs_error("[%s] Attach reject [Cause:%d]", ogs_error("[%s] Attach reject [Cause:%d]",
mme_ue->imsi_bcd, session_cause); mme_ue->imsi_bcd, session_cause);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE, OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE); OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -228,7 +228,7 @@ void mme_s11_handle_create_session_response(
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) { if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
ogs_error("[%s] Attach reject [Cause:%d]", ogs_error("[%s] Attach reject [Cause:%d]",
mme_ue->imsi_bcd, session_cause); mme_ue->imsi_bcd, session_cause);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE, OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE); OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -236,7 +236,8 @@ void mme_s11_handle_create_session_response(
} else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) { } else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
ogs_error("[%s] TAU reject [Cause:%d]", ogs_error("[%s] TAU reject [Cause:%d]",
mme_ue->imsi_bcd, session_cause); mme_ue->imsi_bcd, session_cause);
r = nas_eps_send_tau_reject(mme_ue, OGS_NAS_EMM_CAUSE_NETWORK_FAILURE); r = nas_eps_send_tau_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
} }
@ -266,7 +267,7 @@ void mme_s11_handle_create_session_response(
mme_ue->imsi_bcd, bearer_cause); mme_ue->imsi_bcd, bearer_cause);
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) { if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd); ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE, OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE); OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -286,7 +287,7 @@ void mme_s11_handle_create_session_response(
ogs_error("[%s] GTP Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause); ogs_error("[%s] GTP Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause);
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) { if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd); ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE, OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE); OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -441,7 +442,7 @@ void mme_s11_handle_create_session_response(
} else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) { } else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
/* 3GPP TS 23.401 D.3.6 step 13, 14: */ /* 3GPP TS 23.401 D.3.6 step 13, 14: */
mme_s6a_send_ulr(mme_ue); mme_s6a_send_ulr(mme_ue->enb_ue, mme_ue);
} else if (create_action == OGS_GTP_CREATE_IN_UPLINK_NAS_TRANSPORT) { } else if (create_action == OGS_GTP_CREATE_IN_UPLINK_NAS_TRANSPORT) {
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(session->paa.session_type)); ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(session->paa.session_type));
r = nas_eps_send_activate_default_bearer_context_request( r = nas_eps_send_activate_default_bearer_context_request(
@ -680,7 +681,7 @@ void mme_s11_handle_delete_session_response(
* of the detach accept from UE */ * of the detach accept from UE */
} else if (action == OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST) { } else if (action == OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST) {
if (mme_sess_count(mme_ue) == 1) /* Last Session */ { if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
mme_s6a_send_air(mme_ue, NULL); mme_s6a_send_air(mme_ue->enb_ue, mme_ue, NULL);
} }
} else if (action == OGS_GTP_DELETE_SEND_DETACH_ACCEPT) { } else if (action == OGS_GTP_DELETE_SEND_DETACH_ACCEPT) {
@ -742,7 +743,7 @@ void mme_s11_handle_delete_session_response(
&mme_ue->pdn_connectivity_request); &mme_ue->pdn_connectivity_request);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("nas_eps_send_emm_to_esm() failed"); ogs_error("nas_eps_send_emm_to_esm() failed");
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);

View File

@ -118,6 +118,16 @@ uint8_t mme_s6a_handle_ula(
return OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED; return OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED;
} }
} else if (mme_ue->nas_eps.type == MME_EPS_TYPE_TAU_REQUEST) { } else if (mme_ue->nas_eps.type == MME_EPS_TYPE_TAU_REQUEST) {
if (!SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
ogs_warn("No PDN Connection : UE[%s]", mme_ue->imsi_bcd);
return OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK;
}
if (!ACTIVE_EPS_BEARERS_IS_AVAIABLE(mme_ue)) {
ogs_warn("No active EPS bearers : IMSI[%s]", mme_ue->imsi_bcd);
return OGS_NAS_EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED;
}
r = nas_eps_send_tau_accept(mme_ue, r = nas_eps_send_tau_accept(mme_ue,
S1AP_ProcedureCode_id_InitialContextSetup); S1AP_ProcedureCode_id_InitialContextSetup);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);

View File

@ -566,6 +566,12 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
goto cleanup; goto cleanup;
} }
enb_ue = enb_ue_cycle(e->enb_ue);
/*
* The 'enb_ue' context is not checked
* because the status is checked in the sending routine.
*/
switch (s6a_message->cmd_code) { switch (s6a_message->cmd_code) {
case OGS_DIAM_S6A_CMD_CODE_AUTHENTICATION_INFORMATION: case OGS_DIAM_S6A_CMD_CODE_AUTHENTICATION_INFORMATION:
ogs_debug("OGS_DIAM_S6A_CMD_CODE_AUTHENTICATION_INFORMATION"); ogs_debug("OGS_DIAM_S6A_CMD_CODE_AUTHENTICATION_INFORMATION");
@ -573,12 +579,8 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) {
ogs_info("[%s] Attach reject [OGS_NAS_EMM_CAUSE:%d]", ogs_info("[%s] Attach reject [OGS_NAS_EMM_CAUSE:%d]",
mme_ue->imsi_bcd, emm_cause); mme_ue->imsi_bcd, emm_cause);
enb_ue = enb_ue_cycle(mme_ue->enb_ue); r = nas_eps_send_attach_reject(
if (!enb_ue) { enb_ue, mme_ue, emm_cause,
ogs_error("S1 context has already been removed");
break;
}
r = nas_eps_send_attach_reject(mme_ue, emm_cause,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
@ -594,21 +596,29 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
ogs_debug("OGS_DIAM_S6A_CMD_CODE_UPDATE_LOCATION"); ogs_debug("OGS_DIAM_S6A_CMD_CODE_UPDATE_LOCATION");
emm_cause = mme_s6a_handle_ula(mme_ue, s6a_message); emm_cause = mme_s6a_handle_ula(mme_ue, s6a_message);
if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) {
ogs_info("[%s] Attach reject [OGS_NAS_EMM_CAUSE:%d]", if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) {
mme_ue->imsi_bcd, emm_cause); ogs_info("[%s] Attach reject [OGS_NAS_EMM_CAUSE:%d]",
enb_ue = enb_ue_cycle(mme_ue->enb_ue); mme_ue->imsi_bcd, emm_cause);
if (!enb_ue) { r = nas_eps_send_attach_reject(
ogs_error("S1 context has already been removed"); enb_ue, mme_ue, emm_cause,
break; OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
} ogs_expect(r == OGS_OK);
r = nas_eps_send_attach_reject(mme_ue, emm_cause, ogs_assert(r != OGS_ERROR);
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); } else if (mme_ue->nas_eps.type == MME_EPS_TYPE_TAU_REQUEST) {
ogs_expect(r == OGS_OK); ogs_info("[%s] TAU reject [OGS_NAS_EMM_CAUSE:%d]",
ogs_assert(r != OGS_ERROR); mme_ue->imsi_bcd, emm_cause);
r = nas_eps_send_tau_reject(
enb_ue, mme_ue, emm_cause);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
} else
ogs_error("Invalid Type[%d]", mme_ue->nas_eps.type);
r = s1ap_send_ue_context_release_command(enb_ue, r = s1ap_send_ue_context_release_command(enb_ue,
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release, S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0); mme_ue_cycle(enb_ue->mme_ue) ?
S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE :
S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE, 0);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
} }

View File

@ -76,32 +76,27 @@ int nas_eps_send_emm_to_esm(mme_ue_t *mme_ue,
return rv; return rv;
} }
int nas_eps_send_to_downlink_nas_transport(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf) int nas_eps_send_to_downlink_nas_transport(
enb_ue_t *enb_ue, ogs_pkbuf_t *pkbuf)
{ {
int rv; int rv;
ogs_pkbuf_t *s1apbuf = NULL; ogs_pkbuf_t *s1apbuf = NULL;
ogs_assert(pkbuf); ogs_assert(pkbuf);
if (!mme_ue_cycle(mme_ue)) { if (!enb_ue_cycle(enb_ue)) {
ogs_error("UE(mme-ue) context has already been removed");
ogs_pkbuf_free(pkbuf);
return OGS_NOTFOUND;
}
if (!enb_ue_cycle(mme_ue->enb_ue)) {
ogs_error("S1 context has already been removed"); ogs_error("S1 context has already been removed");
ogs_pkbuf_free(pkbuf); ogs_pkbuf_free(pkbuf);
return OGS_NOTFOUND; return OGS_NOTFOUND;
} }
s1apbuf = s1ap_build_downlink_nas_transport(mme_ue->enb_ue, pkbuf); s1apbuf = s1ap_build_downlink_nas_transport(enb_ue, pkbuf);
if (!s1apbuf) { if (!s1apbuf) {
ogs_error("s1ap_build_downlink_nas_transport() failed"); ogs_error("s1ap_build_downlink_nas_transport() failed");
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_enb(mme_ue, s1apbuf); rv = s1ap_send_to_enb_ue(enb_ue, s1apbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -183,7 +178,7 @@ int nas_eps_send_attach_accept(mme_ue_t *mme_ue)
return rv; return rv;
} }
int nas_eps_send_attach_reject(mme_ue_t *mme_ue, int nas_eps_send_attach_reject(enb_ue_t *enb_ue, mme_ue_t *mme_ue,
ogs_nas_emm_cause_t emm_cause, ogs_nas_esm_cause_t esm_cause) ogs_nas_emm_cause_t emm_cause, ogs_nas_esm_cause_t esm_cause)
{ {
int rv; int rv;
@ -195,7 +190,7 @@ int nas_eps_send_attach_reject(mme_ue_t *mme_ue,
return OGS_NOTFOUND; return OGS_NOTFOUND;
} }
if (!enb_ue_cycle(mme_ue->enb_ue)) { if (!enb_ue_cycle(enb_ue)) {
ogs_error("S1 context has already been removed"); ogs_error("S1 context has already been removed");
return OGS_NOTFOUND; return OGS_NOTFOUND;
} }
@ -218,7 +213,7 @@ int nas_eps_send_attach_reject(mme_ue_t *mme_ue,
ogs_error("emm_build_attach_reject() failed"); ogs_error("emm_build_attach_reject() failed");
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -260,7 +255,7 @@ int nas_eps_send_identity_request(mme_ue_t *mme_ue)
ogs_timer_start(mme_ue->t3470.timer, ogs_timer_start(mme_ue->t3470.timer,
mme_timer_cfg(MME_TIMER_T3470)->duration); mme_timer_cfg(MME_TIMER_T3470)->duration);
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -302,7 +297,7 @@ int nas_eps_send_authentication_request(mme_ue_t *mme_ue)
ogs_timer_start(mme_ue->t3460.timer, ogs_timer_start(mme_ue->t3460.timer,
mme_timer_cfg(MME_TIMER_T3460)->duration); mme_timer_cfg(MME_TIMER_T3460)->duration);
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -344,7 +339,7 @@ int nas_eps_send_security_mode_command(mme_ue_t *mme_ue)
ogs_timer_start(mme_ue->t3460.timer, ogs_timer_start(mme_ue->t3460.timer,
mme_timer_cfg(MME_TIMER_T3460)->duration); mme_timer_cfg(MME_TIMER_T3460)->duration);
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -373,7 +368,7 @@ int nas_eps_send_authentication_reject(mme_ue_t *mme_ue)
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -415,7 +410,7 @@ int nas_eps_send_detach_request(mme_ue_t *mme_ue)
ogs_timer_start(mme_ue->t3422.timer, ogs_timer_start(mme_ue->t3422.timer,
mme_timer_cfg(MME_TIMER_T3422)->duration); mme_timer_cfg(MME_TIMER_T3422)->duration);
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -447,7 +442,7 @@ int nas_eps_send_detach_accept(mme_ue_t *mme_ue)
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("nas_eps_send_to_downlink_nas_transport() failed"); ogs_error("nas_eps_send_to_downlink_nas_transport() failed");
return rv; return rv;
@ -485,7 +480,7 @@ int nas_eps_send_pdn_connectivity_reject(
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) { if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
/* During the UE-attach process, we'll send Attach-Reject /* During the UE-attach process, we'll send Attach-Reject
* with pyggybacking PDN-connectivity-Reject */ * with pyggybacking PDN-connectivity-Reject */
rv = nas_eps_send_attach_reject(mme_ue, rv = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_ESM_FAILURE, esm_cause); OGS_NAS_EMM_CAUSE_ESM_FAILURE, esm_cause);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("nas_eps_send_attach_reject() failed"); ogs_error("nas_eps_send_attach_reject() failed");
@ -504,7 +499,7 @@ int nas_eps_send_pdn_connectivity_reject(
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, esmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, esmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
} }
@ -549,7 +544,7 @@ int nas_eps_send_esm_information_request(mme_bearer_t *bearer)
ogs_timer_start(bearer->t3489.timer, ogs_timer_start(bearer->t3489.timer,
mme_timer_cfg(MME_TIMER_T3489)->duration); mme_timer_cfg(MME_TIMER_T3489)->duration);
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, esmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, esmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -691,7 +686,7 @@ int nas_eps_send_modify_bearer_context_request(
rv = nas_eps_send_to_enb(mme_ue, s1apbuf); rv = nas_eps_send_to_enb(mme_ue, s1apbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
} else { } else {
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, esmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, esmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
} }
@ -763,7 +758,7 @@ int nas_eps_send_bearer_resource_allocation_reject(
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, esmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, esmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -794,7 +789,7 @@ int nas_eps_send_bearer_resource_modification_reject(
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, esmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, esmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -847,7 +842,7 @@ int nas_eps_send_tau_accept(
rv = nas_eps_send_to_enb(mme_ue, s1apbuf); rv = nas_eps_send_to_enb(mme_ue, s1apbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
} else if (procedureCode == S1AP_ProcedureCode_id_downlinkNASTransport) { } else if (procedureCode == S1AP_ProcedureCode_id_downlinkNASTransport) {
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
} else } else
ogs_assert_if_reached(); ogs_assert_if_reached();
@ -855,7 +850,8 @@ int nas_eps_send_tau_accept(
return rv; return rv;
} }
int nas_eps_send_tau_reject(mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause) int nas_eps_send_tau_reject(
enb_ue_t *enb_ue, mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause)
{ {
int rv; int rv;
ogs_pkbuf_t *emmbuf = NULL; ogs_pkbuf_t *emmbuf = NULL;
@ -865,7 +861,7 @@ int nas_eps_send_tau_reject(mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause)
return OGS_NOTFOUND; return OGS_NOTFOUND;
} }
if (!enb_ue_cycle(mme_ue->enb_ue)) { if (!enb_ue_cycle(enb_ue)) {
ogs_error("S1 context has already been removed"); ogs_error("S1 context has already been removed");
return OGS_NOTFOUND; return OGS_NOTFOUND;
} }
@ -879,14 +875,14 @@ int nas_eps_send_tau_reject(mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause)
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
} }
int nas_eps_send_service_reject(mme_ue_t *mme_ue, int nas_eps_send_service_reject(
ogs_nas_emm_cause_t emm_cause) enb_ue_t *enb_ue, mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause)
{ {
int rv; int rv;
ogs_pkbuf_t *emmbuf = NULL; ogs_pkbuf_t *emmbuf = NULL;
@ -896,7 +892,7 @@ int nas_eps_send_service_reject(mme_ue_t *mme_ue,
return OGS_NOTFOUND; return OGS_NOTFOUND;
} }
if (!enb_ue_cycle(mme_ue->enb_ue)) { if (!enb_ue_cycle(enb_ue)) {
ogs_error("S1 context has already been removed"); ogs_error("S1 context has already been removed");
return OGS_NOTFOUND; return OGS_NOTFOUND;
} }
@ -910,7 +906,7 @@ int nas_eps_send_service_reject(mme_ue_t *mme_ue,
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -939,7 +935,7 @@ int nas_eps_send_cs_service_notification(mme_ue_t *mme_ue)
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;
@ -972,7 +968,7 @@ int nas_eps_send_downlink_nas_transport(
return OGS_ERROR; return OGS_ERROR;
} }
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf); rv = nas_eps_send_to_downlink_nas_transport(mme_ue->enb_ue, emmbuf);
ogs_expect(rv == OGS_OK); ogs_expect(rv == OGS_OK);
return rv; return rv;

View File

@ -30,10 +30,10 @@ int nas_eps_send_to_enb(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf);
int nas_eps_send_emm_to_esm( int nas_eps_send_emm_to_esm(
mme_ue_t *mme_ue, ogs_nas_esm_message_container_t *esm_message_container); mme_ue_t *mme_ue, ogs_nas_esm_message_container_t *esm_message_container);
int nas_eps_send_to_downlink_nas_transport( int nas_eps_send_to_downlink_nas_transport(
mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf); enb_ue_t *enb_ue, ogs_pkbuf_t *pkbuf);
int nas_eps_send_attach_accept(mme_ue_t *mme_ue); int nas_eps_send_attach_accept(mme_ue_t *mme_ue);
int nas_eps_send_attach_reject(mme_ue_t *mme_ue, int nas_eps_send_attach_reject(enb_ue_t *enb_ue, mme_ue_t *mme_ue,
ogs_nas_emm_cause_t emm_cause, ogs_nas_esm_cause_t esm_cause); ogs_nas_emm_cause_t emm_cause, ogs_nas_esm_cause_t esm_cause);
int nas_eps_send_identity_request(mme_ue_t *mme_ue); int nas_eps_send_identity_request(mme_ue_t *mme_ue);
@ -64,10 +64,11 @@ int nas_eps_send_bearer_resource_modification_reject(
int nas_eps_send_tau_accept( int nas_eps_send_tau_accept(
mme_ue_t *mme_ue, S1AP_ProcedureCode_t procedureCode); mme_ue_t *mme_ue, S1AP_ProcedureCode_t procedureCode);
int nas_eps_send_tau_reject(mme_ue_t *mme_ue, ogs_nas_esm_cause_t emm_cause); int nas_eps_send_tau_reject(
enb_ue_t *enb_ue, mme_ue_t *mme_ue, ogs_nas_esm_cause_t emm_cause);
int nas_eps_send_service_reject( int nas_eps_send_service_reject(
mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause); enb_ue_t *enb_ue, mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause);
int nas_eps_send_cs_service_notification(mme_ue_t *mme_ue); int nas_eps_send_cs_service_notification(mme_ue_t *mme_ue);
int nas_eps_send_downlink_nas_transport( int nas_eps_send_downlink_nas_transport(

View File

@ -124,7 +124,7 @@ void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
return; return;
error: error:
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -210,7 +210,7 @@ void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
ogs_plmn_id_hexdump(&lai->nas_plmn_id), lai->lac); ogs_plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
} }
r = nas_eps_send_attach_reject(mme_ue, r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);

View File

@ -103,15 +103,318 @@ static void test3_func(abts_case *tc, void *data)
} }
#endif #endif
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_PROTECTION_SCHEME_NULL;
mobile_identity_suci.home_network_pki_value = 0;
test_ue = test_ue_add_by_suci(&mobile_identity_suci, "3746000006");
ogs_assert(test_ue);
test_ue->e_cgi.cell_id = 0x1079baf0;
test_ue->nas.ksi = 0;
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_GTP2_RAT_TYPE_EUTRAN);
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.request_type =
OGS_NAS_EPS_REQUEST_TYPE_INITIAL;
esmbuf = testesm_build_pdn_connectivity_request(sess, false);
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.ms_network_capability = 1;
test_ue->attach_request_param.tmsi_status = 1;
test_ue->attach_request_param.mobile_station_classmark_2 = 1;
test_ue->attach_request_param.ue_usage_setting = 1;
emmbuf = testemm_build_attach_request(test_ue, esmbuf, true, false);
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 */
sess->esm_information_param.epco = 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 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 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);
/* 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, false, false);
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 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);
/* Send Service Request */
emmbuf = testemm_build_service_request(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Data, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Service Reject */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Receive UEContextReleaseCommand */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id;
mme_ue_s1ap_id = test_ue->mme_ue_s1ap_id;
/* TAU Reject */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Receive UEContextReleaseCommand */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UEContextReleaseComplete for TAU Reject */
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);
/* Send UEContextReleaseComplete for Service Reject */
test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id;
test_ue->mme_ue_s1ap_id = mme_ue_s1ap_id;
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_crash(abts_suite *suite) abts_suite *test_crash(abts_suite *suite)
{ {
suite = ADD_SUITE(suite) suite = ADD_SUITE(suite)
abts_run_test(suite, test1_func, NULL); abts_run_test(suite, test1_func, NULL);
abts_run_test(suite, test2_func, NULL); abts_run_test(suite, test2_func, NULL);
#if 0 #if 0 /* Commenting to suppress error messages */
abts_run_test(suite, test3_func, NULL); abts_run_test(suite, test3_func, NULL);
#endif #endif
abts_run_test(suite, test4_func, NULL);
return suite; return suite;
} }

View File

@ -165,6 +165,8 @@ void testemm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
testemm_handle_tau_accept(test_ue, testemm_handle_tau_accept(test_ue,
&message.emm.tracking_area_update_accept); &message.emm.tracking_area_update_accept);
break; break;
case OGS_NAS_EPS_TRACKING_AREA_UPDATE_REJECT:
break;
case OGS_NAS_EPS_EMM_INFORMATION: case OGS_NAS_EPS_EMM_INFORMATION:
break; break;
case OGS_NAS_EPS_CS_SERVICE_NOTIFICATION: case OGS_NAS_EPS_CS_SERVICE_NOTIFICATION:

View File

@ -47,6 +47,7 @@ void tests1ap_handle_downlink_nas_transport(
S1AP_DownlinkNASTransport_IEs_t *ie = NULL; S1AP_DownlinkNASTransport_IEs_t *ie = NULL;
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL; S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_NAS_PDU_t *NAS_PDU = NULL; S1AP_NAS_PDU_t *NAS_PDU = NULL;
ogs_assert(test_ue); ogs_assert(test_ue);
@ -64,6 +65,9 @@ void tests1ap_handle_downlink_nas_transport(
case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID: case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID:
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID; MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
break; break;
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_NAS_PDU: case S1AP_ProtocolIE_ID_id_NAS_PDU:
NAS_PDU = &ie->value.choice.NAS_PDU; NAS_PDU = &ie->value.choice.NAS_PDU;
break; break;
@ -74,6 +78,8 @@ void tests1ap_handle_downlink_nas_transport(
if (MME_UE_S1AP_ID) if (MME_UE_S1AP_ID)
test_ue->mme_ue_s1ap_id = *MME_UE_S1AP_ID; test_ue->mme_ue_s1ap_id = *MME_UE_S1AP_ID;
if (ENB_UE_S1AP_ID)
test_ue->enb_ue_s1ap_id = *ENB_UE_S1AP_ID;
if (NAS_PDU) if (NAS_PDU)
tests1ap_send_to_nas(test_ue, NAS_PDU); tests1ap_send_to_nas(test_ue, NAS_PDU);
@ -91,6 +97,7 @@ void tests1ap_handle_initial_context_setup_request(
S1AP_InitialContextSetupRequestIEs_t *ie = NULL; S1AP_InitialContextSetupRequestIEs_t *ie = NULL;
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL; S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_NAS_PDU_t *NAS_PDU = NULL; S1AP_NAS_PDU_t *NAS_PDU = NULL;
S1AP_E_RABToBeSetupListCtxtSUReq_t *E_RABToBeSetupListCtxtSUReq = NULL; S1AP_E_RABToBeSetupListCtxtSUReq_t *E_RABToBeSetupListCtxtSUReq = NULL;
@ -109,6 +116,9 @@ void tests1ap_handle_initial_context_setup_request(
case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID: case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID:
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID; MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
break; break;
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq: case S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq:
E_RABToBeSetupListCtxtSUReq = E_RABToBeSetupListCtxtSUReq =
&ie->value.choice.E_RABToBeSetupListCtxtSUReq; &ie->value.choice.E_RABToBeSetupListCtxtSUReq;
@ -120,6 +130,8 @@ void tests1ap_handle_initial_context_setup_request(
if (MME_UE_S1AP_ID) if (MME_UE_S1AP_ID)
test_ue->mme_ue_s1ap_id = *MME_UE_S1AP_ID; test_ue->mme_ue_s1ap_id = *MME_UE_S1AP_ID;
if (ENB_UE_S1AP_ID)
test_ue->enb_ue_s1ap_id = *ENB_UE_S1AP_ID;
for (i = 0; i < E_RABToBeSetupListCtxtSUReq->list.count; i++) { for (i = 0; i < E_RABToBeSetupListCtxtSUReq->list.count; i++) {
S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t *ie2 = NULL; S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t *ie2 = NULL;