diff --git a/src/amf/amf-sm.c b/src/amf/amf-sm.c index c0e6ab069..75b5747ff 100644 --- a/src/amf/amf-sm.c +++ b/src/amf/amf-sm.c @@ -488,10 +488,9 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) ogs_info("[%s:%d] Release SM context [%d]", amf_ue->supi, sess->psi, sbi_message.res_status); } else { - ogs_error("[%s] HTTP response error [%d]", - amf_ue->supi, sbi_message.res_status); + ogs_error("[%s:%d] HTTP response error [%d]", + amf_ue->supi, sess->psi, sbi_message.res_status); } - amf_nsmf_pdusession_handle_release_sm_context(sess, state); break; @@ -518,6 +517,8 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) * So, if CreateSMContext is failed, * we'll clear SM_CONTEXT_REF. */ + ogs_error("[%s:%d] create_sm_context failed() [%d]", + amf_ue->supi, sess->psi, sbi_message.res_status); AMF_SESS_CLEAR(sess); } END diff --git a/src/amf/context.h b/src/amf/context.h index f10262887..884be010c 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -509,6 +509,8 @@ typedef struct amf_sess_s { /* SMF sends the RESPONSE * of [POST] /nsmf-pdusession/v1/sm-contexts */ char *sm_context_ref; + bool pdu_session_release_complete_received; + bool pdu_session_resource_release_response_received; /* SMF sends the REQUEST * of [POST] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages */ @@ -818,7 +820,6 @@ amf_sess_t *amf_sess_add(amf_ue_t *amf_ue, uint8_t psi); sbi_object = &(__sESS)->sbi; \ ogs_assert(sbi_object); \ \ - ogs_error("AMF_SESS_CLEAR"); \ if (ogs_list_count(&sbi_object->xact_list)) { \ ogs_error("SBI running [%d]", \ ogs_list_count(&sbi_object->xact_list)); \ diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c index a6720c171..46110e3bb 100644 --- a/src/amf/gmm-handler.c +++ b/src/amf/gmm-handler.c @@ -1099,6 +1099,23 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue, if (!sess) { sess = amf_sess_add(amf_ue, *pdu_session_id); ogs_assert(sess); + } else { + /* + * These are variables that should be initialized + * when a PDU session establishment message is received + * for an existing session. + * + * It should be noted that XXX_recieved, which is initialized now, + * has a different initialization location than XXX_gsm_type. + * + * XXX_received is initialized in the ESTABLISHMENT phase, + * but XXX_gsm_type is initialized in the RELEASE phase + * when a PDU session release command with a Reactivation Request + * and a PDU session release complete are sent simultaneously. + */ + sess->pdu_session_resource_release_response_received = false; + sess->pdu_session_release_complete_received = false; + } } else { sess = amf_sess_find_by_psi(amf_ue, *pdu_session_id); @@ -1386,8 +1403,10 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue, } break; case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE: - /* Prevent to invoke SMF for this session */ - CLEAR_SM_CONTEXT_REF(sess); + sess->pdu_session_release_complete_received = true; + if (sess->pdu_session_resource_release_response_received == + true) + CLEAR_SM_CONTEXT_REF(sess); break; default: break; diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index 300bbac5f..0c6f0ef75 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -2514,7 +2514,12 @@ void ngap_handle_pdu_session_resource_release_response( ogs_assert(r != OGS_ERROR); ogs_pkbuf_free(param.n2smbuf); + + sess->pdu_session_resource_release_response_received = true; + if (sess->pdu_session_release_complete_received == true) + CLEAR_SM_CONTEXT_REF(sess); } + } void ngap_handle_uplink_ran_configuration_transfer( diff --git a/src/amf/nsmf-handler.c b/src/amf/nsmf-handler.c index 8a1bd0717..f011b7e9e 100644 --- a/src/amf/nsmf-handler.c +++ b/src/amf/nsmf-handler.c @@ -1056,8 +1056,21 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state) ogs_error("[%s:%d] Do not remove Session due to Reactivation-requested", amf_ue->supi, sess->psi); - /* Initialize the context instead of using amf_sess_remove() */ - + /* + * Issue #2917 + * + * These are variables that need to be initialized + * when a PDU session release command with a Reactivation Request + * and a PDU session release complete are sent at the same time. + * + * It is important to note that XXX_gsm_type, which is initialized now, + * has a different initialization location than + * pdu_session_release_complete_received/ + * pdu_session_resource_release_response_received + * + * XXX_received is initialized in the ESTABLISHMENT phase, + * but XXX_gsm_type must be initialized in the RELEASE phase. + */ sess->old_gsm_type = 0; sess->current_gsm_type = 0; @@ -1068,7 +1081,7 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state) } else { ogs_info("[%s:%d] Release SM Context [state:%d]", amf_ue->supi, sess->psi, state); - amf_sess_remove(sess); + AMF_SESS_CLEAR(sess); } if (state == AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) { diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index 2ae170203..be10244b9 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -284,8 +284,6 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e) case SMF_EVT_5GSM_MESSAGE: nas_message = e->nas.message; ogs_assert(nas_message); - sess = e->sess; - ogs_assert(sess); stream = e->h.sbi.data; ogs_assert(stream); smf_ue = sess->smf_ue; @@ -436,8 +434,6 @@ void smf_gsm_state_wait_5gc_sm_policy_association(ogs_fsm_t *s, smf_event_t *e) sbi_message = e->h.sbi.message; ogs_assert(sbi_message); - sess = e->sess; - ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); @@ -850,8 +846,6 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) sbi_message = e->h.sbi.message; ogs_assert(sbi_message); - sess = e->sess; - ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); @@ -1002,8 +996,6 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) case SMF_EVT_5GSM_MESSAGE: nas_message = e->nas.message; ogs_assert(nas_message); - sess = e->sess; - ogs_assert(sess); stream = e->h.sbi.data; ogs_assert(stream); smf_ue = sess->smf_ue; @@ -1069,8 +1061,6 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) break; case SMF_EVT_NGAP_MESSAGE: - sess = e->sess; - ogs_assert(sess); stream = e->h.sbi.data; ogs_assert(stream); smf_ue = sess->smf_ue; @@ -1364,8 +1354,6 @@ void smf_gsm_state_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e) sbi_message = e->h.sbi.message; ogs_assert(sbi_message); - sess = e->sess; - ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); @@ -1588,8 +1576,6 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e) sbi_message = e->h.sbi.message; ogs_assert(sbi_message); - sess = e->sess; - ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); @@ -1638,8 +1624,6 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e) break; case SMF_EVT_NGAP_MESSAGE: - sess = e->sess; - ogs_assert(sess); stream = e->h.sbi.data; ogs_assert(stream); smf_ue = sess->smf_ue; @@ -1713,8 +1697,6 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e) case SMF_EVT_5GSM_MESSAGE: nas_message = e->nas.message; ogs_assert(nas_message); - sess = e->sess; - ogs_assert(sess); stream = e->h.sbi.data; ogs_assert(stream); smf_ue = sess->smf_ue; @@ -1794,8 +1776,6 @@ void smf_gsm_state_5gc_n1_n2_reject(ogs_fsm_t *s, smf_event_t *e) sbi_message = e->h.sbi.message; ogs_assert(sbi_message); - sess = e->sess; - ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); @@ -1874,11 +1854,19 @@ void smf_gsm_state_5gc_n1_n2_reject(ogs_fsm_t *s, smf_event_t *e) void smf_gsm_state_5gc_session_will_deregister(ogs_fsm_t *s, smf_event_t *e) { + smf_sess_t *sess = NULL; + + ogs_sbi_stream_t *stream = NULL; + ogs_sbi_message_t *sbi_message = NULL; + ogs_assert(s); ogs_assert(e); smf_sm_debug(e); + sess = e->sess; + ogs_assert(sess); + switch (e->h.id) { case OGS_FSM_ENTRY_SIG: break; @@ -1886,6 +1874,41 @@ void smf_gsm_state_5gc_session_will_deregister(ogs_fsm_t *s, smf_event_t *e) case OGS_FSM_EXIT_SIG: break; + case OGS_EVENT_SBI_SERVER: + sbi_message = e->h.sbi.message; + ogs_assert(sbi_message); + stream = e->h.sbi.data; + ogs_assert(stream); + + SWITCH(sbi_message->h.service.name) + CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION) + SWITCH(sbi_message->h.resource.component[2]) + CASE(OGS_SBI_RESOURCE_NAME_RELEASE) + ogs_assert(true == ogs_sbi_send_response( + stream, OGS_SBI_HTTP_STATUS_TOO_MANY_REQUESTS)); + break; + DEFAULT + ogs_error("Invalid resource name [%s]", + sbi_message->h.resource.component[2]); + ogs_assert(true == + ogs_sbi_server_send_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message, + "Invalid resource name [%s]", + sbi_message->h.resource.component[2])); + OGS_FSM_TRAN(s, smf_gsm_state_exception); + END + break; + + DEFAULT + ogs_error("Invalid API name [%s]", sbi_message->h.service.name); + ogs_assert(true == + ogs_sbi_server_send_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, sbi_message, + "Invalid API name", sbi_message->h.service.name)); + OGS_FSM_TRAN(s, smf_gsm_state_exception); + END + break; + default: ogs_error("Unknown event %s", smf_event_get_name(e)); break; diff --git a/tests/registration/dereg-test.c b/tests/registration/dereg-test.c index bddd07ec6..a12ec8474 100644 --- a/tests/registration/dereg-test.c +++ b/tests/registration/dereg-test.c @@ -1584,6 +1584,304 @@ static void test5_func(abts_case *tc, void *data) test_ue_remove(test_ue); } +static void test6_issues2917_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *ngap; + ogs_socknode_t *gtpu; + ogs_pkbuf_t *gmmbuf; + ogs_pkbuf_t *gsmbuf; + ogs_pkbuf_t *nasbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_ngap_message_t message; + int i; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *qos_flow = NULL; + + 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, "0000203190"); + ogs_assert(test_ue); + + test_ue->nr_cgi.cell_id = 0x40001; + + test_ue->nas.registration.tsc = 0; + test_ue->nas.registration.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.registration.follow_on_request = 1; + test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL; + + test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; + test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca"; + + /* gNB connects to AMF */ + ngap = testngap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, ngap); + + /* gNB connects to UPF */ + gtpu = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu); + + /* Send NG-Setup Reqeust */ + sendbuf = testngap_build_ng_setup_request(0x4000, 26); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive NG-Setup Response */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, 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 Registration request */ + gmmbuf = testgmm_build_registration_request(test_ue, NULL, false, false); + ABTS_PTR_NOTNULL(tc, gmmbuf); + + test_ue->registration_request_param.gmm_capability = 1; + test_ue->registration_request_param.s1_ue_network_capability = 1; + test_ue->registration_request_param.requested_nssai = 1; + test_ue->registration_request_param.last_visited_registered_tai = 1; + test_ue->registration_request_param.ue_usage_setting = 1; + nasbuf = testgmm_build_registration_request(test_ue, NULL, false, false); + ABTS_PTR_NOTNULL(tc, nasbuf); + + sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, + NGAP_RRCEstablishmentCause_mo_Signalling, false, true); + 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 response */ + gmmbuf = testgmm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + gmmbuf = testgmm_build_security_mode_complete(test_ue, nasbuf); + 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 InitialContextSetupRequest + + * Registration accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_InitialContextSetup, + test_ue->ngap_procedure_code); + + /* Send UERadioCapabilityInfoIndication */ + sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send InitialContextSetupResponse */ + sendbuf = testngap_build_initial_context_setup_response(test_ue, false); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Registration complete */ + gmmbuf = testgmm_build_registration_complete(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Configuration update command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send PDU session establishment request */ + sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5); + ogs_assert(sess); + + sess->ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + sess->ul_nas_transport_param.dnn = 1; + sess->ul_nas_transport_param.s_nssai = 1; + + sess->pdu_session_establishment_param.ssc_mode = 1; + sess->pdu_session_establishment_param.epco = 1; + + gsmbuf = testgsm_build_pdu_session_establishment_request(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + 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 PDUSessionResourceSetupRequest + + * DL NAS transport + + * PDU session establishment accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceSetup, + test_ue->ngap_procedure_code); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_qfi(sess, 1); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send PDUSessionResourceSetupResponse */ + sendbuf = testngap_sess_build_pdu_session_resource_setup_response(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send PDU Session release request */ + sess->ul_nas_transport_param.request_type = 0; + sess->ul_nas_transport_param.dnn = 0; + sess->ul_nas_transport_param.s_nssai = 0; + + sess->pdu_session_establishment_param.ssc_mode = 0; + sess->pdu_session_establishment_param.epco = 0; + + gsmbuf = testgsm_build_pdu_session_release_request(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + 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 PDUSessionResourceReleaseCommand + + * DL NAS transport + + * PDU session release command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); + + /* Send UplinkNASTransport + + * UL NAS trasnport + + * PDU session resource release complete */ + sess->ul_nas_transport_param.request_type = 0; + sess->ul_nas_transport_param.dnn = 0; + sess->ul_nas_transport_param.s_nssai = 0; + + sess->pdu_session_establishment_param.ssc_mode = 0; + sess->pdu_session_establishment_param.epco = 0; + + gsmbuf = testgsm_build_pdu_session_release_complete(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + 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); + + /* Send PDUSessionResourceReleaseResponse */ + sendbuf = testngap_build_pdu_session_resource_release_response(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(100); + + /* Send De-registration request */ + gmmbuf = testgmm_build_de_registration_request(test_ue, 1, true, true); + 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 UEContextReleaseCommand */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_UEContextRelease, + test_ue->ngap_procedure_code); + + /* Send UEContextReleaseComplete */ + 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); + + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue)); + + /* gNB disonncect from UPF */ + testgnb_gtpu_close(gtpu); + + /* gNB disonncect from AMF */ + testgnb_ngap_close(ngap); + + /* Clear Test UE Context */ + test_ue_remove(test_ue); +} + abts_suite *test_dereg(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -1593,6 +1891,7 @@ abts_suite *test_dereg(abts_suite *suite) abts_run_test(suite, test3_func, NULL); abts_run_test(suite, test4_func, NULL); abts_run_test(suite, test5_func, NULL); + abts_run_test(suite, test6_issues2917_func, NULL); return suite; }