forked from acouzens/open5gs
Add EMM/GMM handler in exception state [#569]
This commit is contained in:
parent
6dace84232
commit
62d95be036
|
@ -742,26 +742,6 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
|||
ngap_send_ran_ue_context_release_command(amf_ue->ran_ue,
|
||||
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
|
||||
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
|
||||
|
||||
/*
|
||||
* Pull #569 : State should be initialized again.
|
||||
*
|
||||
* However, we cannot initialize the state in all cases.
|
||||
*
|
||||
* In TS24.501 Ch 5.5.1.3.8 Abnormal cases on the network side
|
||||
*
|
||||
* d) REGISTRATION REQUEST with 5GS registration type IE set to
|
||||
* "mobility registration updating" or "periodic registration updating"
|
||||
* received after the REGISTRATION ACCEPT message has been sent and
|
||||
* before the REGISTRATION COMPLETE message is received.
|
||||
*
|
||||
* Since, we have to do this special case, it is desirable
|
||||
* to handle it directly inside the state(gmm-sm.c).
|
||||
*/
|
||||
#if 0
|
||||
amf_ue_fsm_fini(amf_ue);
|
||||
amf_ue_fsm_init(amf_ue);
|
||||
#endif
|
||||
}
|
||||
amf_ue_associate_ran_ue(amf_ue, ran_ue);
|
||||
}
|
||||
|
|
|
@ -1011,13 +1011,25 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
|
||||
{
|
||||
int rv, xact_count = 0;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
amf_sess_t *sess = NULL;
|
||||
ran_ue_t *ran_ue = NULL;
|
||||
ogs_nas_5gs_message_t *nas_message = NULL;
|
||||
ogs_nas_security_header_type_t h;
|
||||
|
||||
ogs_assert(e);
|
||||
amf_sm_debug(e);
|
||||
|
||||
amf_ue = e->amf_ue;
|
||||
ogs_assert(amf_ue);
|
||||
if (e->sess) {
|
||||
sess = e->sess;
|
||||
amf_ue = sess->amf_ue;
|
||||
ogs_assert(amf_ue);
|
||||
} else {
|
||||
amf_ue = e->amf_ue;
|
||||
ogs_assert(amf_ue);
|
||||
}
|
||||
|
||||
switch (e->id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
|
@ -1033,8 +1045,70 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
|
|||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
break;
|
||||
default:
|
||||
ogs_error("GMM exception occurred [%s]", amf_event_get_name(e));
|
||||
|
||||
case AMF_EVT_5GMM_MESSAGE:
|
||||
nas_message = e->nas.message;
|
||||
ogs_assert(nas_message);
|
||||
|
||||
ran_ue = amf_ue->ran_ue;
|
||||
ogs_assert(ran_ue);
|
||||
|
||||
h.type = e->nas.type;
|
||||
amf_ue->nas.ngapProcedureCode = e->ngap.code;
|
||||
|
||||
xact_count = amf_sess_xact_count(amf_ue);
|
||||
|
||||
switch (nas_message->gmm.h.message_type) {
|
||||
case OGS_NAS_5GS_REGISTRATION_REQUEST:
|
||||
rv = gmm_handle_registration_request(
|
||||
amf_ue, &nas_message->gmm.registration_request);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("gmm_handle_registration_request() failed");
|
||||
OGS_FSM_TRAN(s, gmm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
|
||||
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
|
||||
nas_5gs_send_identity_request(amf_ue);
|
||||
break;
|
||||
}
|
||||
|
||||
if (h.integrity_protected && SECURITY_CONTEXT_IS_VALID(amf_ue)) {
|
||||
|
||||
rv = gmm_handle_registration_update(
|
||||
amf_ue, &nas_message->gmm.registration_request);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("gmm_handle_registration_update() failed");
|
||||
OGS_FSM_TRAN(s, gmm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
||||
if (amf_sess_xact_count(amf_ue) == xact_count)
|
||||
nas_5gs_send_registration_accept(amf_ue);
|
||||
|
||||
OGS_FSM_TRAN(s, &gmm_state_registered);
|
||||
|
||||
} else {
|
||||
|
||||
amf_sbi_send_release_all_sessions(
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
if (amf_sess_xact_count(amf_ue) == xact_count) {
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OpenAPI_nf_type_AUSF, amf_ue, NULL,
|
||||
amf_nausf_auth_build_authenticate);
|
||||
}
|
||||
|
||||
OGS_FSM_TRAN(s, &gmm_state_authentication);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Unknown message [%d]", nas_message->gmm.h.message_type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Unknown event[%s]", amf_event_get_name(e));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -434,26 +434,6 @@ void ngap_handle_initial_ue_message(amf_gnb_t *gnb, ogs_ngap_message_t *message)
|
|||
ngap_send_ran_ue_context_release_command(amf_ue->ran_ue,
|
||||
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
|
||||
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
|
||||
|
||||
/*
|
||||
* Pull #569 : State should be initialized again.
|
||||
*
|
||||
* However, we cannot initialize the state in all cases.
|
||||
*
|
||||
* In TS24.501 Ch 5.5.1.3.8 Abnormal cases on the network side
|
||||
*
|
||||
* d) REGISTRATION REQUEST with 5GS registration type IE set to
|
||||
* "mobility registration updating" or "periodic registration updating"
|
||||
* received after the REGISTRATION ACCEPT message has been sent and
|
||||
* before the REGISTRATION COMPLETE message is received.
|
||||
*
|
||||
* Since, we have to do this special case, it is desirable
|
||||
* to handle it directly inside the state(gmm-sm.c).
|
||||
*/
|
||||
#if 0
|
||||
amf_ue_fsm_fini(amf_ue);
|
||||
amf_ue_fsm_init(amf_ue);
|
||||
#endif
|
||||
}
|
||||
amf_ue_associate_ran_ue(amf_ue, ran_ue);
|
||||
}
|
||||
|
|
|
@ -105,9 +105,10 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
|
|||
|
||||
switch (e->id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
return;
|
||||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
return;
|
||||
break;
|
||||
|
||||
case MME_EVT_EMM_MESSAGE:
|
||||
message = e->nas_message;
|
||||
ogs_assert(message);
|
||||
|
@ -590,7 +591,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
|
|||
if (rv != OGS_OK) {
|
||||
ogs_error("emm_handle_attach_request() failed");
|
||||
OGS_FSM_TRAN(s, emm_state_exception);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
|
@ -610,7 +611,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
|
|||
if (rv != OGS_OK) {
|
||||
ogs_error("emm_handle_detach_request() failed");
|
||||
OGS_FSM_TRAN(s, emm_state_exception);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
mme_send_delete_session_or_detach(mme_ue);
|
||||
|
@ -681,7 +682,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
|
|||
nas_eps_send_service_reject(mme_ue,
|
||||
EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED);
|
||||
OGS_FSM_TRAN(s, &emm_state_exception);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (message->emm.h.message_type) {
|
||||
|
@ -864,7 +865,7 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
|
|||
if (rv != OGS_OK) {
|
||||
ogs_error("emm_handle_attach_request() failed");
|
||||
OGS_FSM_TRAN(s, emm_state_exception);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
mme_gtp_send_delete_all_sessions(mme_ue);
|
||||
|
@ -884,7 +885,7 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
|
|||
if (rv != OGS_OK) {
|
||||
ogs_error("emm_handle_detach_request() failed");
|
||||
OGS_FSM_TRAN(s, emm_state_exception);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
mme_send_delete_session_or_detach(mme_ue);
|
||||
|
@ -916,7 +917,12 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
|
|||
|
||||
void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
|
||||
{
|
||||
int rv;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
ogs_nas_eps_message_t *message = NULL;
|
||||
ogs_nas_security_header_type_t h;
|
||||
|
||||
ogs_assert(e);
|
||||
mme_sm_debug(e);
|
||||
|
@ -931,8 +937,61 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
|
|||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
break;
|
||||
|
||||
case MME_EVT_EMM_MESSAGE:
|
||||
message = e->nas_message;
|
||||
ogs_assert(message);
|
||||
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
ogs_assert(enb_ue);
|
||||
|
||||
h.type = e->nas_type;
|
||||
|
||||
switch (message->emm.h.message_type) {
|
||||
case OGS_NAS_EPS_ATTACH_REQUEST:
|
||||
ogs_debug("[EMM] Attach request[%s]", mme_ue->imsi_bcd);
|
||||
rv = emm_handle_attach_request(
|
||||
mme_ue, &message->emm.attach_request, e->pkbuf);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("emm_handle_attach_request() failed");
|
||||
OGS_FSM_TRAN(s, emm_state_exception);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!MME_UE_HAVE_IMSI(mme_ue)) {
|
||||
CLEAR_MME_UE_TIMER(mme_ue->t3470);
|
||||
nas_eps_send_identity_request(mme_ue);
|
||||
break;
|
||||
}
|
||||
|
||||
if (h.integrity_protected && SECURITY_CONTEXT_IS_VALID(mme_ue)) {
|
||||
rv = nas_eps_send_emm_to_esm(mme_ue,
|
||||
&mme_ue->pdn_connectivity_request);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("nas_eps_send_emm_to_esm() failed");
|
||||
nas_eps_send_attach_reject(mme_ue,
|
||||
EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
|
||||
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
|
||||
OGS_FSM_TRAN(s, &emm_state_exception);
|
||||
} else {
|
||||
OGS_FSM_TRAN(s, &emm_state_initial_context_setup);
|
||||
}
|
||||
} else {
|
||||
if (SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
|
||||
mme_gtp_send_delete_all_sessions(mme_ue);
|
||||
} else {
|
||||
mme_s6a_send_air(mme_ue, NULL);
|
||||
}
|
||||
OGS_FSM_TRAN(s, &emm_state_authentication);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_warn("Unknown message[%d]", message->emm.h.message_type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Unknown event[%s]", mme_event_get_name(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -416,6 +416,63 @@ static void test1_func(abts_case *tc, void *data)
|
|||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
tests1ap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send Attach Request - No Integrity */
|
||||
sess->pdn_connectivity_param.eit = 1;
|
||||
sess->pdn_connectivity_param.pco = 1;
|
||||
esmbuf = testesm_build_pdn_connectivity_request(sess);
|
||||
ABTS_PTR_NOTNULL(tc, esmbuf);
|
||||
|
||||
memset(&test_ue->attach_request_param,
|
||||
0, sizeof(test_ue->attach_request_param));
|
||||
test_ue->attach_request_param.ms_network_feature_support = 1;
|
||||
emmbuf = testemm_build_attach_request(test_ue, esmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, emmbuf);
|
||||
|
||||
sendbuf = test_s1ap_build_initial_ue_message(
|
||||
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive OLD UE Context Release Command */
|
||||
enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id;
|
||||
|
||||
recvbuf = testenb_s1ap_read(s1ap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
tests1ap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send OLD UE Context Release Complete */
|
||||
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id;
|
||||
|
||||
/* Receive Authentication request */
|
||||
recvbuf = testenb_s1ap_read(s1ap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
tests1ap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send Authentication failure - MAC failure */
|
||||
emmbuf = testemm_build_authentication_failure(
|
||||
test_ue, EMM_CAUSE_MAC_FAILURE, 0);
|
||||
ABTS_PTR_NOTNULL(tc, emmbuf);
|
||||
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Authentication reject */
|
||||
recvbuf = testenb_s1ap_read(s1ap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
tests1ap_recv(test_ue, recvbuf);
|
||||
|
||||
/* 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);
|
||||
|
|
|
@ -213,6 +213,50 @@ static void test1_func(abts_case *tc, void *data)
|
|||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send Registration request */
|
||||
test_ue->registration_request_param.gmm_capability = 1;
|
||||
gmmbuf = testgmm_build_registration_request(test_ue, NULL);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, false);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* OLD Receive UE context release command */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send OLD UE Context Release Complete */
|
||||
sendbuf = testngap_build_ue_context_release_complete(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Authentication request */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send Authentication failure - MAC failure */
|
||||
gmmbuf = testgmm_build_authentication_failure(
|
||||
test_ue, OGS_5GMM_CAUSE_MAC_FAILURE, 0);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Authentication reject */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Receive UE context release command */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send UE context release complete */
|
||||
sendbuf = testngap_build_ue_context_release_complete(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
|
|
Loading…
Reference in New Issue