From 4d5b38c8f4a32c140afd6fb337429f2d8e983995 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Thu, 30 Jul 2020 22:10:20 -0400 Subject: [PATCH] Fix the AMF crash [#521] --- configs/open5gs/mme.yaml.in | 2 +- lib/sbi/path.c | 5 +- lib/sbi/server.c | 9 ++-- src/amf/context.c | 9 +++- src/amf/context.h | 1 + src/amf/namf-handler.c | 47 ++++++++++++++--- src/amf/ngap-handler.c | 92 +++++++++++++++++++++++---------- src/amf/ngap-path.h | 2 +- src/amf/nsmf-handler.c | 38 +++++++++++++- src/ausf/nnrf-handler.c | 4 -- src/smf/gsm-handler.c | 5 +- src/smf/gsm-handler.h | 3 +- src/smf/gsm-sm.c | 24 +++++---- src/smf/meson.build | 2 - src/smf/n4-handler.c | 4 +- src/smf/nas-path.c | 4 +- src/smf/nas-path.h | 3 +- src/smf/ngap-handler.c | 11 ++-- src/smf/ngap-handler.h | 2 +- src/smf/ngap-path.c | 4 +- src/smf/ngap-path.h | 3 +- src/smf/nnrf-build.c | 26 ---------- src/smf/nnrf-build.h | 36 ------------- src/smf/nnrf-handler.c | 4 -- src/smf/nsmf-handler.c | 37 ++++++------- src/smf/nsmf-handler.h | 6 +-- src/smf/nudm-handler.c | 2 +- src/smf/pfcp-path.c | 19 ++++--- src/smf/pfcp-path.h | 9 ++-- src/smf/sbi-path.c | 16 ++---- src/smf/sbi-path.h | 10 ++-- src/smf/smf-sm.c | 4 ++ src/udm/nnrf-handler.c | 4 -- tests/registration/dereg-test.c | 1 + 34 files changed, 250 insertions(+), 198 deletions(-) delete mode 100644 src/smf/nnrf-build.c delete mode 100644 src/smf/nnrf-build.h diff --git a/configs/open5gs/mme.yaml.in b/configs/open5gs/mme.yaml.in index b185251bc..a4c39d6ec 100644 --- a/configs/open5gs/mme.yaml.in +++ b/configs/open5gs/mme.yaml.in @@ -292,7 +292,7 @@ sgw: # # o By default, the PGW uses the first PGW node. # - To use a different APN for each PGW, specify gtpc.apn as the APN name. -# - If the HSS uses WebUI to set the PGW IP for eacho UE, +# - If the HSS uses WebUI to set the PGW IP for each UE, # you can use a specific PGW node for each UE. # # o Two PGW are defined. 127.0.0.3:2123 is used. diff --git a/lib/sbi/path.c b/lib/sbi/path.c index e942d85df..5f3a20ac0 100644 --- a/lib/sbi/path.c +++ b/lib/sbi/path.c @@ -101,9 +101,6 @@ void ogs_sbi_send( ogs_freeaddrinfo(addr); } - ogs_timer_start(sbi_object->client_wait.timer, - sbi_object->client_wait.duration); - ogs_sbi_client_send_request( client, sbi_object->client_cb, request, sbi_object); } @@ -122,6 +119,8 @@ bool ogs_sbi_discover_and_send( ogs_assert(build); sbi_object->running_count++; + ogs_timer_start(sbi_object->client_wait.timer, + sbi_object->client_wait.duration); sbi_object->nf_type = nf_type; if (sbi_object->request) diff --git a/lib/sbi/server.c b/lib/sbi/server.c index 413f1ba5d..cb6ba10da 100644 --- a/lib/sbi/server.c +++ b/lib/sbi/server.c @@ -339,6 +339,7 @@ void ogs_sbi_server_send_response( ogs_sbi_session_t *session, ogs_sbi_response_t *response) { int ret; + int status; struct MHD_Connection *connection = NULL; struct MHD_Response *mhd_response; @@ -385,16 +386,18 @@ void ogs_sbi_server_send_response( MHD_add_response_header(mhd_response, key, val); } + status = response->status; + request = session->request; + ogs_assert(request); + ogs_sbi_response_free(response); session_remove(session); - request = session->request; - ogs_assert(request); request->poll = ogs_pollset_add(ogs_sbi_self()->pollset, OGS_POLLOUT, mhd_socket, run, mhd_daemon); ogs_assert(request->poll); - ret = MHD_queue_response(connection, response->status, mhd_response); + ret = MHD_queue_response(connection, status, mhd_response); if (ret != MHD_YES) { ogs_fatal("MHD_queue_response_error [%d]", ret); ogs_assert_if_reached(); diff --git a/src/amf/context.c b/src/amf/context.c index b3c01a53f..da9191816 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -1199,7 +1199,8 @@ void amf_ue_remove(amf_ue_t *amf_ue) /* Free SBI object memory */ if (amf_ue->sbi.running_count) ogs_error("[%s] SBI running [%d]", - amf_ue->supi, amf_ue->sbi.running_count); + amf_ue->supi ? amf_ue->supi : "Unknown", + amf_ue->sbi.running_count); ogs_sbi_object_free(&amf_ue->sbi); ogs_timer_delete(amf_ue->sbi.client_wait.timer); @@ -1497,7 +1498,8 @@ void amf_sess_remove(amf_sess_t *sess) /* Free SBI object memory */ if (sess->sbi.running_count) ogs_error("[%s:%d] SBI running [%d]", - sess->amf_ue->supi, sess->psi, sess->sbi.running_count); + sess->amf_ue->supi ? sess->amf_ue->supi : "Unknown", + sess->psi, sess->sbi.running_count); ogs_sbi_object_free(&sess->sbi); ogs_timer_delete(sess->sbi.client_wait.timer); @@ -1509,6 +1511,9 @@ void amf_sess_remove(amf_sess_t *sess) if (sess->dnn) ogs_free(sess->dnn); + if (sess->pdu_session_establishment_accept) + ogs_pkbuf_free(sess->pdu_session_establishment_accept); + OGS_NAS_CLEAR_DATA(&sess->ue_pco); OGS_TLV_CLEAR_DATA(&sess->pgw_pco); diff --git a/src/amf/context.h b/src/amf/context.h index 397caf0a7..44b344037 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -409,6 +409,7 @@ typedef struct amf_sess_s { OpenAPI_resource_status_e resource_status; ogs_pkbuf_t *n2smbuf; + ogs_pkbuf_t *pdu_session_establishment_accept; /* last payload for sending back to the UE */ uint8_t payload_container_type; diff --git a/src/amf/namf-handler.c b/src/amf/namf-handler.c index ac2b55eef..ab82a1bbc 100644 --- a/src/amf/namf-handler.c +++ b/src/amf/namf-handler.c @@ -21,7 +21,7 @@ #include "nsmf-handler.h" #include "nas-path.h" -#include "gmm-build.h" +#include "ngap-path.h" int amf_namf_comm_handle_n1_n2_message_transfer( ogs_sbi_session_t *session, ogs_sbi_message_t *recvmsg) @@ -34,6 +34,9 @@ int amf_namf_comm_handle_n1_n2_message_transfer( ogs_pkbuf_t *n1smbuf = NULL; ogs_pkbuf_t *n2smbuf = NULL; + ogs_pkbuf_t *gmmbuf = NULL; + ogs_pkbuf_t *ngapbuf = NULL; + char *supi = NULL; uint8_t pdu_session_id = OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED; @@ -140,7 +143,37 @@ int amf_namf_comm_handle_n1_n2_message_transfer( n2smbuf = ogs_pkbuf_copy(n2smbuf); ogs_assert(n2smbuf); - nas_send_pdu_session_establishment_accept(sess, n1smbuf, n2smbuf); + if (sess->pdu_session_establishment_accept) { + ogs_pkbuf_free(sess->pdu_session_establishment_accept); + sess->pdu_session_establishment_accept = NULL; + } + + gmmbuf = gmm_build_dl_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0); + ogs_assert(gmmbuf); + + ngapbuf = ngap_build_pdu_session_resource_setup_request( + sess, gmmbuf, n2smbuf); + ogs_assert(ngapbuf); + + status = OGS_SBI_HTTP_STATUS_OK; + + if (SESSION_CONTEXT_IN_SMF(sess)) { + /* + * [1-CLIENT] /nsmf-pdusession/v1/sm-contexts + * [2-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages + * + * If [2-SERVER] arrives after [1-CLIENT], + * sm-context-ref is created in [1-CLIENT]. + * So, the PDU session establishment accpet can be transmitted now. + */ + if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) { + ogs_error("nas_5gs_send_to_gnb() failed"); + status = OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR; + } + } else { + sess->pdu_session_establishment_accept = ngapbuf; + } memset(&N1N2MessageTransferRspData, 0, sizeof(N1N2MessageTransferRspData)); N1N2MessageTransferRspData.cause = @@ -150,9 +183,6 @@ int amf_namf_comm_handle_n1_n2_message_transfer( sendmsg.N1N2MessageTransferRspData = &N1N2MessageTransferRspData; - status = OGS_SBI_HTTP_STATUS_OK; - /* TODO : OGS_SBI_HTTP_STATUS_ACCEPTED */ - response = ogs_sbi_build_response(&sendmsg, status); ogs_assert(response); ogs_sbi_server_send_response(session, response); @@ -229,7 +259,8 @@ int amf_namf_callback_handle_sm_context_status( sess->resource_status = StatusInfo->resource_status; if (sess->resource_status == OpenAPI_resource_status_RELEASED) { - ogs_info("[%s:%d] SM context status released", amf_ue->supi, sess->psi); + ogs_debug("[%s:%d] SM context status released", + amf_ue->supi, sess->psi); /* * Race condition for PDU session release complete @@ -243,8 +274,10 @@ int amf_namf_callback_handle_sm_context_status( * If NOTIFICATION comes after the CLIENT response is received, * sync is done. So, the session context can be removed. */ - if (amf_sess_sync_done(sess)) + if (amf_sess_sync_done(sess)) { + ogs_debug("[%s:%d] SM context remove", amf_ue->supi, sess->psi); amf_nsmf_pdu_session_handle_release_sm_context(sess); + } } cleanup: diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index cb098a45a..746171bcb 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -356,7 +356,8 @@ void ngap_handle_initial_ue_message(amf_gnb_t *gnb, ogs_ngap_message_t *message) NAS_PDU = &ie->value.choice.NAS_PDU; break; case NGAP_ProtocolIE_ID_id_UserLocationInformation: - UserLocationInformation = &ie->value.choice.UserLocationInformation; + UserLocationInformation = + &ie->value.choice.UserLocationInformation; break; case NGAP_ProtocolIE_ID_id_FiveG_S_TMSI: FiveG_S_TMSI = &ie->value.choice.FiveG_S_TMSI; @@ -480,6 +481,7 @@ void ngap_handle_uplink_nas_transport( NGAP_UplinkNASTransport_t *UplinkNASTransport = NULL; NGAP_UplinkNASTransport_IEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_NAS_PDU_t *NAS_PDU = NULL; @@ -497,6 +499,9 @@ void ngap_handle_uplink_nas_transport( for (i = 0; i < UplinkNASTransport->protocolIEs.list.count; i++) { ie = UplinkNASTransport->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; @@ -512,7 +517,7 @@ void ngap_handle_uplink_nas_transport( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -520,7 +525,7 @@ void ngap_handle_uplink_nas_transport( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -529,7 +534,8 @@ void ngap_handle_uplink_nas_transport( if (!ran_ue) { ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); - ngap_send_error_indication(gnb, NULL, &amf_ue_ngap_id, + ngap_send_error_indication( + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; @@ -561,6 +567,7 @@ void ngap_handle_ue_radio_capability_info_indication( *UERadioCapabilityInfoIndication = NULL; NGAP_UERadioCapabilityInfoIndicationIEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_UERadioCapability_t *UERadioCapability = NULL; @@ -580,6 +587,9 @@ void ngap_handle_ue_radio_capability_info_indication( i < UERadioCapabilityInfoIndication->protocolIEs.list.count; i++) { ie = UERadioCapabilityInfoIndication->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; @@ -595,7 +605,7 @@ void ngap_handle_ue_radio_capability_info_indication( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -603,7 +613,7 @@ void ngap_handle_ue_radio_capability_info_indication( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -613,7 +623,7 @@ void ngap_handle_ue_radio_capability_info_indication( ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); ngap_send_error_indication( - gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id, + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; @@ -650,6 +660,7 @@ void ngap_handle_initial_context_setup_response( NGAP_InitialContextSetupResponse_t *InitialContextSetupResponse = NULL; NGAP_InitialContextSetupResponseIEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_PDUSessionResourceSetupListCxtRes_t *PDUSessionList = NULL; NGAP_PDUSessionResourceSetupItemCxtRes_t *PDUSessionItem = NULL; @@ -670,6 +681,9 @@ void ngap_handle_initial_context_setup_response( for (i = 0; i < InitialContextSetupResponse->protocolIEs.list.count; i++) { ie = InitialContextSetupResponse->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; @@ -686,7 +700,7 @@ void ngap_handle_initial_context_setup_response( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -694,7 +708,7 @@ void ngap_handle_initial_context_setup_response( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -704,7 +718,7 @@ void ngap_handle_initial_context_setup_response( ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); ngap_send_error_indication( - gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id, + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; @@ -795,6 +809,7 @@ void ngap_handle_initial_context_setup_failure( NGAP_InitialContextSetupFailure_t *InitialContextSetupFailure = NULL; NGAP_InitialContextSetupFailureIEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_Cause_t *Cause = NULL; @@ -813,6 +828,9 @@ void ngap_handle_initial_context_setup_failure( for (i = 0; i < InitialContextSetupFailure->protocolIEs.list.count; i++) { ie = InitialContextSetupFailure->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; @@ -828,7 +846,7 @@ void ngap_handle_initial_context_setup_failure( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -836,7 +854,7 @@ void ngap_handle_initial_context_setup_failure( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -846,7 +864,7 @@ void ngap_handle_initial_context_setup_failure( ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); ngap_send_error_indication( - gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id, + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; @@ -1015,6 +1033,7 @@ void ngap_handle_ue_context_release_request( NGAP_UEContextReleaseRequest_t *UEContextReleaseRequest = NULL; NGAP_UEContextReleaseRequest_IEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_PDUSessionResourceListCxtRelReq_t *PDUSessionList = NULL; NGAP_PDUSessionResourceItemCxtRelReq_t *PDUSessionItem = NULL; @@ -1035,6 +1054,9 @@ void ngap_handle_ue_context_release_request( for (i = 0; i < UEContextReleaseRequest->protocolIEs.list.count; i++) { ie = UEContextReleaseRequest->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; @@ -1053,7 +1075,7 @@ void ngap_handle_ue_context_release_request( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1061,7 +1083,7 @@ void ngap_handle_ue_context_release_request( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1070,7 +1092,8 @@ void ngap_handle_ue_context_release_request( if (!ran_ue) { ogs_warn("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); - ngap_send_error_indication(gnb, NULL, &amf_ue_ngap_id, + ngap_send_error_indication( + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; @@ -1167,6 +1190,7 @@ void ngap_handle_ue_context_release_complete( NGAP_UEContextReleaseComplete_t *UEContextReleaseComplete = NULL; NGAP_UEContextReleaseComplete_IEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; ogs_assert(gnb); @@ -1184,6 +1208,9 @@ void ngap_handle_ue_context_release_complete( for (i = 0; i < UEContextReleaseComplete->protocolIEs.list.count; i++) { ie = UEContextReleaseComplete->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; @@ -1196,7 +1223,7 @@ void ngap_handle_ue_context_release_complete( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1204,7 +1231,7 @@ void ngap_handle_ue_context_release_complete( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1213,7 +1240,8 @@ void ngap_handle_ue_context_release_complete( if (!ran_ue) { ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); - ngap_send_error_indication(gnb, NULL, &amf_ue_ngap_id, + ngap_send_error_indication( + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; @@ -1280,6 +1308,7 @@ void ngap_handle_pdu_session_resource_setup_response( NGAP_PDUSessionResourceSetupResponse_t *PDUSessionResourceSetupResponse; NGAP_PDUSessionResourceSetupResponseIEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_PDUSessionResourceSetupListSURes_t *PDUSessionList = NULL; NGAP_PDUSessionResourceSetupItemSURes_t *PDUSessionItem = NULL; @@ -1301,11 +1330,15 @@ void ngap_handle_pdu_session_resource_setup_response( i++) { ie = PDUSessionResourceSetupResponse->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; case NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSURes: - PDUSessionList = &ie->value.choice.PDUSessionResourceSetupListSURes; + PDUSessionList = + &ie->value.choice.PDUSessionResourceSetupListSURes; break; default: break; @@ -1316,7 +1349,7 @@ void ngap_handle_pdu_session_resource_setup_response( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1324,7 +1357,7 @@ void ngap_handle_pdu_session_resource_setup_response( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1334,7 +1367,7 @@ void ngap_handle_pdu_session_resource_setup_response( ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); ngap_send_error_indication( - gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id, + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; @@ -1436,9 +1469,11 @@ void ngap_handle_pdu_session_resource_release_response( amf_nsmf_pdu_session_update_sm_context_param_t param; NGAP_SuccessfulOutcome_t *successfulOutcome = NULL; - NGAP_PDUSessionResourceReleaseResponse_t *PDUSessionResourceReleaseResponse; + NGAP_PDUSessionResourceReleaseResponse_t + *PDUSessionResourceReleaseResponse; NGAP_PDUSessionResourceReleaseResponseIEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_PDUSessionResourceReleasedListRelRes_t *PDUSessionList = NULL; NGAP_PDUSessionResourceReleasedItemRelRes_t *PDUSessionItem = NULL; @@ -1460,6 +1495,9 @@ void ngap_handle_pdu_session_resource_release_response( i++) { ie = PDUSessionResourceReleaseResponse->protocolIEs.list.array[i]; switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; break; @@ -1476,7 +1514,7 @@ void ngap_handle_pdu_session_resource_release_response( if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1484,7 +1522,7 @@ void ngap_handle_pdu_session_resource_release_response( if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id) != 0) { ogs_error("Invalid AMF_UE_NGAP_ID"); - ngap_send_error_indication(gnb, NULL, NULL, + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); return; } @@ -1494,7 +1532,7 @@ void ngap_handle_pdu_session_resource_release_response( ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", (long long)amf_ue_ngap_id); ngap_send_error_indication( - gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id, + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); return; diff --git a/src/amf/ngap-path.h b/src/amf/ngap-path.h index 67884817c..040e82b4c 100644 --- a/src/amf/ngap-path.h +++ b/src/amf/ngap-path.h @@ -20,7 +20,7 @@ #ifndef NGAP_PATH_H #define NGAP_PATH_H -#include "context.h" +#include "ngap-build.h" #ifdef __cplusplus extern "C" { diff --git a/src/amf/nsmf-handler.c b/src/amf/nsmf-handler.c index 31add1ad5..14e82fe1e 100644 --- a/src/amf/nsmf-handler.c +++ b/src/amf/nsmf-handler.c @@ -27,11 +27,12 @@ int amf_nsmf_pdu_session_handle_create_sm_context( amf_sess_t *sess, ogs_sbi_message_t *recvmsg) { + int rv; + ogs_assert(sess); ogs_assert(recvmsg); if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_CREATED) { - int rv; ogs_sbi_message_t message; ogs_sbi_header_t header; @@ -64,6 +65,34 @@ int amf_nsmf_pdu_session_handle_create_sm_context( return OGS_ERROR; } + if (sess->pdu_session_establishment_accept) { + /* + * [1-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages + * [2-CLIENT] /nsmf-pdusession/v1/sm-contexts + * + * If [1-SERVER] arrives before [2-CLIENT], + * there is no sm-context-ref. The PDU session establishment accept + * stored in [1-SERVER] is now trasnmitted to gNB. + */ + amf_ue_t *amf_ue = sess->amf_ue; + ogs_assert(amf_ue); + + rv = nas_5gs_send_to_gnb(amf_ue, + sess->pdu_session_establishment_accept); + + sess->pdu_session_establishment_accept = NULL; + + if (rv != OGS_OK) { + ogs_error("[%d:%d] nas_5gs_send_to_gnb() failed", + sess->psi, sess->pti); + + ogs_sbi_header_free(&header); + nas_5gs_send_back_5gsm_message_from_sbi(sess, + OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR); + return OGS_ERROR; + } + } + if (sess->sm_context_ref) ogs_free(sess->sm_context_ref); sess->sm_context_ref = ogs_strdup(message.h.resource.component[1]); @@ -246,8 +275,13 @@ int amf_nsmf_pdu_session_handle_update_sm_context( * Remove 'amf_sess_t' context to call * amf_nsmf_pdu_session_handle_release_sm_context(). */ - if (sess->resource_status == OpenAPI_resource_status_RELEASED) + ogs_debug("[%s:%d] Receive Update SM context", + amf_ue->supi, sess->psi); + if (sess->resource_status == OpenAPI_resource_status_RELEASED) { + ogs_debug("[%s:%d] SM context remove", + amf_ue->supi, sess->psi); amf_nsmf_pdu_session_handle_release_sm_context(sess); + } } else if (sess->ueUpCnxState == OpenAPI_up_cnx_state_ACTIVATED) { /* diff --git a/src/ausf/nnrf-handler.c b/src/ausf/nnrf-handler.c index e6184d3dc..500ae2792 100644 --- a/src/ausf/nnrf-handler.c +++ b/src/ausf/nnrf-handler.c @@ -296,10 +296,6 @@ void ausf_nnrf_handle_nf_discover( if (!nf_instance) { ogs_error("(NF discover) No [%s]", OpenAPI_nf_type_ToString(sbi_object->nf_type)); - ogs_sbi_server_send_error(session, - OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE, NULL, - "(NF discover) No NF", - OpenAPI_nf_type_ToString(sbi_object->nf_type)); } else { ogs_sbi_send(nf_instance, sbi_object); } diff --git a/src/smf/gsm-handler.c b/src/smf/gsm-handler.c index 2bac66b17..53c74c5a9 100644 --- a/src/smf/gsm-handler.c +++ b/src/smf/gsm-handler.c @@ -24,7 +24,8 @@ #undef OGS_LOG_DOMAIN #define OGS_LOG_DOMAIN __gsm_log_domain -int gsm_handle_pdu_session_establishment_request(smf_sess_t *sess, +int gsm_handle_pdu_session_establishment_request( + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_nas_5gs_pdu_session_establishment_request_t * pdu_session_establishment_request) { @@ -34,10 +35,8 @@ int gsm_handle_pdu_session_establishment_request(smf_sess_t *sess, integrity_protection_maximum_data_rate; ogs_nas_pdu_session_type_t *pdu_session_type = NULL; ogs_nas_ssc_mode_t *ssc_mode = NULL; - ogs_sbi_session_t *session = NULL; ogs_assert(sess); - session = sess->sbi.session; ogs_assert(session); ogs_assert(pdu_session_establishment_request); diff --git a/src/smf/gsm-handler.h b/src/smf/gsm-handler.h index 7a5bc7db7..3a28efadc 100644 --- a/src/smf/gsm-handler.h +++ b/src/smf/gsm-handler.h @@ -26,7 +26,8 @@ extern "C" { #endif -int gsm_handle_pdu_session_establishment_request(smf_sess_t *sess, +int gsm_handle_pdu_session_establishment_request( + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_nas_5gs_pdu_session_establishment_request_t * pdu_session_establishment_request); diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index 361609deb..979c50bed 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -74,13 +74,13 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION) SWITCH(sbi_message->h.resource.component[2]) CASE(OGS_SBI_RESOURCE_NAME_MODIFY) - smf_nsmf_handle_update_sm_context(sess, sbi_message); + smf_nsmf_handle_update_sm_context(sess, session, sbi_message); break; CASE(OGS_SBI_RESOURCE_NAME_RELEASE) - smf_nsmf_handle_release_sm_context(sess, sbi_message); + smf_nsmf_handle_release_sm_context(sess, session, sbi_message); break; DEFAULT - smf_nsmf_handle_create_sm_context(sess, sbi_message); + smf_nsmf_handle_create_sm_context(sess, session, sbi_message); break; END break; @@ -163,15 +163,15 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_assert(nas_message); sess = e->sess; ogs_assert(sess); - session = sess->sbi.session; + session = e->sbi.session; ogs_assert(session); smf_ue = sess->smf_ue; ogs_assert(smf_ue); switch (nas_message->gsm.h.message_type) { case OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST: - rv = gsm_handle_pdu_session_establishment_request( - sess, &nas_message->gsm.pdu_session_establishment_request); + rv = gsm_handle_pdu_session_establishment_request(sess, session, + &nas_message->gsm.pdu_session_establishment_request); if (rv != OGS_OK) { ogs_error("[%s:%d] Cannot handle NAS message", smf_ue->supi, sess->psi); @@ -181,18 +181,18 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) case OGS_NAS_5GS_PDU_SESSION_RELEASE_REQUEST: smf_5gc_pfcp_send_session_deletion_request( - sess, OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED); + sess, session, OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED); break; case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE: - smf_sbi_send_response(sess, OGS_SBI_HTTP_STATUS_NO_CONTENT); + smf_sbi_send_response(session, OGS_SBI_HTTP_STATUS_NO_CONTENT); /* * Race condition for PDU session release complete * - CLIENT : /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify * - SERVER : /namf-callback/v1/{supi}/sm-context-status/{psi}) * - * smf_sbi_send_response(sess, OGS_SBI_HTTP_STATUS_NO_CONTENT); + * smf_sbi_send_response(session, OGS_SBI_HTTP_STATUS_NO_CONTENT); * smf_sbi_send_sm_context_status_notify(sess); * * When executed as above, @@ -220,6 +220,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) case SMF_EVT_NGAP_MESSAGE: sess = e->sess; ogs_assert(sess); + session = e->sbi.session; + ogs_assert(session); smf_ue = sess->smf_ue; ogs_assert(smf_ue); pkbuf = e->pkbuf; @@ -229,7 +231,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) switch (e->ngap.type) { case OpenAPI_n2_sm_info_type_PDU_RES_SETUP_RSP: rv = ngap_handle_pdu_session_resource_setup_response_transfer( - sess, pkbuf); + sess, session, pkbuf); if (rv != OGS_OK) { ogs_error("[%s:%d] Cannot handle NGAP message", smf_ue->supi, sess->psi); @@ -238,7 +240,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) break; case OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP: - smf_sbi_send_response(sess, OGS_SBI_HTTP_STATUS_NO_CONTENT); + smf_sbi_send_response(session, OGS_SBI_HTTP_STATUS_NO_CONTENT); break; default: diff --git a/src/smf/meson.build b/src/smf/meson.build index 8f1911a44..2ffa5ed32 100644 --- a/src/smf/meson.build +++ b/src/smf/meson.build @@ -44,7 +44,6 @@ libsmf_sources = files(''' n4-build.h n4-handler.h bearer-binding.h - nnrf-build.h nnrf-handler.h nudm-build.h nudm-handler.h @@ -75,7 +74,6 @@ libsmf_sources = files(''' n4-build.c n4-handler.c bearer-binding.c - nnrf-build.c nnrf-handler.c nudm-build.c nudm-handler.c diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 01abf0472..1320aad3d 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -265,7 +265,7 @@ void smf_5gc_n4_handle_session_modification_response( /* UPDATE_UpCnxState - SYNC */ sess->smfUpCnxState = sess->ueUpCnxState; - smf_sbi_send_sm_context_updated_data(sess); + smf_sbi_send_sm_context_updated_data(sess, session); } void smf_5gc_n4_handle_session_deletion_response( @@ -319,7 +319,7 @@ void smf_5gc_n4_handle_session_deletion_response( if (trigger == OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED) { - smf_sbi_send_sm_context_updated_data_in_session_deletion(sess); + smf_sbi_send_sm_context_updated_data_in_session_deletion(sess, session); } else { diff --git a/src/smf/nas-path.c b/src/smf/nas-path.c index 67bb43baf..e7f3ec099 100644 --- a/src/smf/nas-path.c +++ b/src/smf/nas-path.c @@ -19,7 +19,8 @@ #include "nas-path.h" -void nas_5gs_send_to_gsm(smf_sess_t *sess, ogs_pkbuf_t *pkbuf) +void nas_5gs_send_to_gsm( + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_pkbuf_t *pkbuf) { int rv; smf_event_t *e = NULL; @@ -30,6 +31,7 @@ void nas_5gs_send_to_gsm(smf_sess_t *sess, ogs_pkbuf_t *pkbuf) e = smf_event_new(SMF_EVT_5GSM_MESSAGE); ogs_assert(e); e->sess = sess; + e->sbi.session = session; e->pkbuf = pkbuf; rv = ogs_queue_push(smf_self()->queue, e); if (rv != OGS_OK) { diff --git a/src/smf/nas-path.h b/src/smf/nas-path.h index 03bd87779..f63a08acf 100644 --- a/src/smf/nas-path.h +++ b/src/smf/nas-path.h @@ -26,7 +26,8 @@ extern "C" { #endif -void nas_5gs_send_to_gsm(smf_sess_t *sess, ogs_pkbuf_t *pkbuf); +void nas_5gs_send_to_gsm( + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_pkbuf_t *pkbuf); #ifdef __cplusplus } diff --git a/src/smf/ngap-handler.c b/src/smf/ngap-handler.c index b9e4ce9e0..0edff0e00 100644 --- a/src/smf/ngap-handler.c +++ b/src/smf/ngap-handler.c @@ -22,9 +22,8 @@ #include "pfcp-path.h" int ngap_handle_pdu_session_resource_setup_response_transfer( - smf_sess_t *sess, ogs_pkbuf_t *pkbuf) + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_pkbuf_t *pkbuf) { - ogs_sbi_session_t *session = NULL; smf_ue_t *smf_ue = NULL; smf_bearer_t *qos_flow = NULL; int rv, i; @@ -45,9 +44,9 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( NGAP_AssociatedQosFlowList_t *associatedQosFlowList = NULL; ogs_assert(pkbuf); - ogs_assert(sess); - session = sess->sbi.session; ogs_assert(session); + + ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); @@ -146,9 +145,9 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( } if (far_update || sess->pfcp_5gc_modify.outer_header_creation_update) - smf_5gc_pfcp_send_session_modification_request(sess); + smf_5gc_pfcp_send_session_modification_request(sess, session); else - smf_sbi_send_sm_context_updated_data(sess); + smf_sbi_send_sm_context_updated_data(sess, session); rv = OGS_OK; diff --git a/src/smf/ngap-handler.h b/src/smf/ngap-handler.h index 41d421239..a967bf0b4 100644 --- a/src/smf/ngap-handler.h +++ b/src/smf/ngap-handler.h @@ -27,7 +27,7 @@ extern "C" { #endif int ngap_handle_pdu_session_resource_setup_response_transfer( - smf_sess_t *sess, ogs_pkbuf_t *pkbuf); + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_pkbuf_t *pkbuf); #ifdef __cplusplus } diff --git a/src/smf/ngap-path.c b/src/smf/ngap-path.c index d3f163788..3373394fd 100644 --- a/src/smf/ngap-path.c +++ b/src/smf/ngap-path.c @@ -19,7 +19,8 @@ #include "ngap-path.h" -void ngap_send_to_n2sm(smf_sess_t *sess, int type, ogs_pkbuf_t *pkbuf) +void ngap_send_to_n2sm(smf_sess_t *sess, + ogs_sbi_session_t *session, int type, ogs_pkbuf_t *pkbuf) { int rv; smf_event_t *e = NULL; @@ -30,6 +31,7 @@ void ngap_send_to_n2sm(smf_sess_t *sess, int type, ogs_pkbuf_t *pkbuf) e = smf_event_new(SMF_EVT_NGAP_MESSAGE); ogs_assert(e); e->sess = sess; + e->sbi.session = session; e->pkbuf = pkbuf; e->ngap.type = type; rv = ogs_queue_push(smf_self()->queue, e); diff --git a/src/smf/ngap-path.h b/src/smf/ngap-path.h index e27faffcd..c09b32b6b 100644 --- a/src/smf/ngap-path.h +++ b/src/smf/ngap-path.h @@ -26,7 +26,8 @@ extern "C" { #endif -void ngap_send_to_n2sm(smf_sess_t *sess, int type, ogs_pkbuf_t *pkbuf); +void ngap_send_to_n2sm(smf_sess_t *sess, + ogs_sbi_session_t *session, int type, ogs_pkbuf_t *pkbuf); #ifdef __cplusplus } diff --git a/src/smf/nnrf-build.c b/src/smf/nnrf-build.c deleted file mode 100644 index f600bcd57..000000000 --- a/src/smf/nnrf-build.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2019 by Sukchan Lee - * - * This file is part of Open5GS. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "nnrf-build.h" - -ogs_sbi_request_t *smf_nnrf_build_test_test( - ogs_sbi_nf_instance_t *nf_instance) -{ - return NULL; -} diff --git a/src/smf/nnrf-build.h b/src/smf/nnrf-build.h deleted file mode 100644 index 804d6f48a..000000000 --- a/src/smf/nnrf-build.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2019 by Sukchan Lee - * - * This file is part of Open5GS. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef SMF_NNRF_BUILD_H -#define SMF_NNRF_BUILD_H - -#include "ogs-sbi.h" -#include "context.h" - -#ifdef __cplusplus -extern "C" { -#endif - -ogs_sbi_request_t *smf_nnrf_build_test_test( - ogs_sbi_nf_instance_t *nf_instance); -#ifdef __cplusplus -} -#endif - -#endif /* SMF_NNRF_BUILD_H */ diff --git a/src/smf/nnrf-handler.c b/src/smf/nnrf-handler.c index b3bedbbc5..9ab461acf 100644 --- a/src/smf/nnrf-handler.c +++ b/src/smf/nnrf-handler.c @@ -296,10 +296,6 @@ void smf_nnrf_handle_nf_discover( if (!nf_instance) { ogs_error("(NF discover) No [%s]", OpenAPI_nf_type_ToString(sbi_object->nf_type)); - ogs_sbi_server_send_error(session, - OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE, NULL, - "(NF discover) No NF", - OpenAPI_nf_type_ToString(sbi_object->nf_type)); } else { ogs_sbi_send(nf_instance, sbi_object); } diff --git a/src/smf/nsmf-handler.c b/src/smf/nsmf-handler.c index e230a2e46..ee1e46dca 100644 --- a/src/smf/nsmf-handler.c +++ b/src/smf/nsmf-handler.c @@ -24,10 +24,9 @@ #include "nsmf-handler.h" bool smf_nsmf_handle_create_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message) + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_sbi_message_t *message) { smf_ue_t *smf_ue = NULL; - ogs_sbi_session_t *session = NULL; ogs_pkbuf_t *n1smbuf = NULL; @@ -40,14 +39,13 @@ bool smf_nsmf_handle_create_sm_context( OpenAPI_plmn_id_nid_t *servingNetwork = NULL; OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL; - ogs_assert(sess); - session = sess->sbi.session; ogs_assert(session); + ogs_assert(message); + + ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); - ogs_assert(message); - SmContextCreateData = message->SmContextCreateData; if (!SmContextCreateData) { ogs_error("[%s:%d] No SmContextCreateData", @@ -197,19 +195,17 @@ bool smf_nsmf_handle_create_sm_context( */ n1smbuf = ogs_pkbuf_copy(n1smbuf); ogs_assert(n1smbuf); - nas_5gs_send_to_gsm(sess, n1smbuf); + nas_5gs_send_to_gsm(sess, session, n1smbuf); return true; } bool smf_nsmf_handle_update_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message) + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_sbi_message_t *message) { int i; smf_ue_t *smf_ue = NULL; - ogs_sbi_session_t *session = NULL; - ogs_sbi_message_t sendmsg; ogs_sbi_response_t *response = NULL; @@ -221,14 +217,13 @@ bool smf_nsmf_handle_update_sm_context( ogs_pkbuf_t *n1smbuf = NULL; ogs_pkbuf_t *n2smbuf = NULL; - ogs_assert(sess); - session = sess->sbi.session; ogs_assert(session); + ogs_assert(message); + + ogs_assert(sess); smf_ue = sess->smf_ue; ogs_assert(smf_ue); - ogs_assert(message); - SmContextUpdateData = message->SmContextUpdateData; if (!SmContextUpdateData) { ogs_error("[%s:%d] No SmContextUpdateData", @@ -292,7 +287,7 @@ bool smf_nsmf_handle_update_sm_context( */ n1smbuf = ogs_pkbuf_copy(n1smbuf); ogs_assert(n1smbuf); - nas_5gs_send_to_gsm(sess, n1smbuf); + nas_5gs_send_to_gsm(sess, session, n1smbuf); return true; @@ -339,7 +334,8 @@ bool smf_nsmf_handle_update_sm_context( */ n2smbuf = ogs_pkbuf_copy(n2smbuf); ogs_assert(n2smbuf); - ngap_send_to_n2sm(sess, SmContextUpdateData->n2_sm_info_type, n2smbuf); + ngap_send_to_n2sm( + sess, session, SmContextUpdateData->n2_sm_info_type, n2smbuf); } else { if (!SmContextUpdateData->up_cnx_state) { @@ -360,7 +356,7 @@ bool smf_nsmf_handle_update_sm_context( ********************************************************/ if (sess->smfUpCnxState == OpenAPI_up_cnx_state_ACTIVATED) { - smf_5gc_pfcp_send_session_modification_request(sess); + smf_5gc_pfcp_send_session_modification_request(sess, session); } else if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) { @@ -498,12 +494,13 @@ bool smf_nsmf_handle_update_sm_context( } bool smf_nsmf_handle_release_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message) + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_sbi_message_t *message) { OpenAPI_sm_context_release_data_t *SmContextReleaseData = NULL; - ogs_assert(sess); + ogs_assert(session); ogs_assert(message); + ogs_assert(sess); SmContextReleaseData = message->SmContextReleaseData; if (SmContextReleaseData) { @@ -532,7 +529,7 @@ bool smf_nsmf_handle_release_sm_context( } } - smf_5gc_pfcp_send_session_deletion_request(sess, + smf_5gc_pfcp_send_session_deletion_request(sess, session, OGS_PFCP_5GC_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT); return true; diff --git a/src/smf/nsmf-handler.h b/src/smf/nsmf-handler.h index 03f4f6e59..89e5e4f96 100644 --- a/src/smf/nsmf-handler.h +++ b/src/smf/nsmf-handler.h @@ -27,11 +27,11 @@ extern "C" { #endif bool smf_nsmf_handle_create_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message); + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_sbi_message_t *message); bool smf_nsmf_handle_update_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message); + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_sbi_message_t *message); bool smf_nsmf_handle_release_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message); + smf_sess_t *sess, ogs_sbi_session_t *session, ogs_sbi_message_t *message); #ifdef __cplusplus } diff --git a/src/smf/nudm-handler.c b/src/smf/nudm-handler.c index d67250b76..53269e73e 100644 --- a/src/smf/nudm-handler.c +++ b/src/smf/nudm-handler.c @@ -337,7 +337,7 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg) pdr->precedence = 0xffffffff; } - smf_5gc_pfcp_send_session_establishment_request(sess); + smf_5gc_pfcp_send_session_establishment_request(sess, session); return true; } diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index 7b8c54b13..7ce3757be 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -216,7 +216,7 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data) sess = data; ogs_assert(sess); - session = sess->sbi.session; + session = xact->assoc_session; ogs_assert(session); smf_ue = sess->smf_ue; ogs_assert(smf_ue); @@ -338,7 +338,8 @@ void smf_pfcp_send_heartbeat_request(ogs_pfcp_node_t *node) ogs_expect(rv == OGS_OK); } -void smf_5gc_pfcp_send_session_establishment_request(smf_sess_t *sess) +void smf_5gc_pfcp_send_session_establishment_request( + smf_sess_t *sess, ogs_sbi_session_t *session) { int rv; ogs_pkbuf_t *n4buf = NULL; @@ -346,6 +347,7 @@ void smf_5gc_pfcp_send_session_establishment_request(smf_sess_t *sess) ogs_pfcp_xact_t *xact = NULL; ogs_assert(sess); + ogs_assert(session); memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE; @@ -357,12 +359,14 @@ void smf_5gc_pfcp_send_session_establishment_request(smf_sess_t *sess) xact = ogs_pfcp_xact_local_create( sess->pfcp_node, &h, n4buf, sess_5gc_timeout, sess); ogs_expect_or_return(xact); + xact->assoc_session = session; rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); } -void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess) +void smf_5gc_pfcp_send_session_modification_request( + smf_sess_t *sess, ogs_sbi_session_t *session) { int rv; ogs_pkbuf_t *n4buf = NULL; @@ -370,6 +374,7 @@ void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess) ogs_pfcp_xact_t *xact = NULL; ogs_assert(sess); + ogs_assert(session); memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; @@ -381,13 +386,14 @@ void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess) xact = ogs_pfcp_xact_local_create( sess->pfcp_node, &h, n4buf, sess_5gc_timeout, sess); ogs_expect_or_return(xact); - xact->assoc_session = sess->sbi.session; + xact->assoc_session = session; rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); } -void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess, int trigger) +void smf_5gc_pfcp_send_session_deletion_request( + smf_sess_t *sess, ogs_sbi_session_t *session, int trigger) { int rv; ogs_pkbuf_t *n4buf = NULL; @@ -395,6 +401,7 @@ void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess, int trigger) ogs_pfcp_xact_t *xact = NULL; ogs_assert(sess); + ogs_assert(session); ogs_assert(trigger); memset(&h, 0, sizeof(ogs_pfcp_header_t)); @@ -407,7 +414,7 @@ void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess, int trigger) xact = ogs_pfcp_xact_local_create( sess->pfcp_node, &h, n4buf, sess_5gc_timeout, sess); ogs_expect_or_return(xact); - xact->assoc_session = sess->sbi.session; + xact->assoc_session = session; xact->trigger = trigger; rv = ogs_pfcp_xact_commit(xact); diff --git a/src/smf/pfcp-path.h b/src/smf/pfcp-path.h index 9080944a9..444ae79b4 100644 --- a/src/smf/pfcp-path.h +++ b/src/smf/pfcp-path.h @@ -34,9 +34,12 @@ void smf_pfcp_send_association_setup_response(ogs_pfcp_xact_t *xact, uint8_t cause); void smf_pfcp_send_heartbeat_request(ogs_pfcp_node_t *node); -void smf_5gc_pfcp_send_session_establishment_request(smf_sess_t *sess); -void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess); -void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess, int trigger); +void smf_5gc_pfcp_send_session_establishment_request( + smf_sess_t *sess, ogs_sbi_session_t *session); +void smf_5gc_pfcp_send_session_modification_request( + smf_sess_t *sess, ogs_sbi_session_t *session); +void smf_5gc_pfcp_send_session_deletion_request( + smf_sess_t *sess, ogs_sbi_session_t *session, int trigger); void smf_epc_pfcp_send_session_establishment_request( smf_sess_t *sess, void *gtp_xact); diff --git a/src/smf/sbi-path.c b/src/smf/sbi-path.c index 2fc15214e..f39f38f75 100644 --- a/src/smf/sbi-path.c +++ b/src/smf/sbi-path.c @@ -145,15 +145,11 @@ void smf_sbi_discover_and_send( } } -void smf_sbi_send_response(smf_sess_t *sess, int status) +void smf_sbi_send_response(ogs_sbi_session_t *session, int status) { - ogs_sbi_session_t *session = NULL; - ogs_sbi_message_t sendmsg; ogs_sbi_response_t *response = NULL; - ogs_assert(sess); - session = sess->sbi.session; ogs_assert(session); memset(&sendmsg, 0, sizeof(sendmsg)); @@ -206,9 +202,9 @@ void smf_sbi_send_sm_context_create_error( ogs_pkbuf_free(n1smbuf); } -void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess) +void smf_sbi_send_sm_context_updated_data( + smf_sess_t *sess, ogs_sbi_session_t *session) { - ogs_sbi_session_t *session = NULL; int status; ogs_sbi_message_t sendmsg; @@ -217,7 +213,6 @@ void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess) OpenAPI_sm_context_updated_data_t SmContextUpdatedData; ogs_assert(sess); - session = sess->sbi.session; ogs_assert(session); memset(&sendmsg, 0, sizeof(sendmsg)); @@ -238,10 +233,10 @@ void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess) ogs_sbi_server_send_response(session, response); } -void smf_sbi_send_sm_context_updated_data_in_session_deletion(smf_sess_t *sess) +void smf_sbi_send_sm_context_updated_data_in_session_deletion( + smf_sess_t *sess, ogs_sbi_session_t *session) { int i; - ogs_sbi_session_t *session = NULL; ogs_sbi_message_t sendmsg; ogs_sbi_response_t *response = NULL; @@ -251,7 +246,6 @@ void smf_sbi_send_sm_context_updated_data_in_session_deletion(smf_sess_t *sess) OpenAPI_ref_to_binary_data_t n2SmInfo; ogs_assert(sess); - session = sess->sbi.session; ogs_assert(session); memset(&sendmsg, 0, sizeof(sendmsg)); diff --git a/src/smf/sbi-path.h b/src/smf/sbi-path.h index 649f1324f..ec7e93fe0 100644 --- a/src/smf/sbi-path.h +++ b/src/smf/sbi-path.h @@ -20,10 +20,10 @@ #ifndef SMF_SBI_PATH_H #define SMF_SBI_PATH_H -#include "nnrf-build.h" #include "nudm-build.h" #include "namf-build.h" #include "gsm-build.h" +#include "nnrf-build.h" #ifdef __cplusplus extern "C" { @@ -37,14 +37,16 @@ void smf_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, smf_sess_t *sess, void *data, ogs_sbi_request_t *(*build)(smf_sess_t *sess, void *data)); -void smf_sbi_send_response(smf_sess_t *sess, int status); +void smf_sbi_send_response(ogs_sbi_session_t *session, int status); void smf_sbi_send_sm_context_create_error( ogs_sbi_session_t *session, int status, const char *title, const char *detail, ogs_pkbuf_t *n1smbuf); -void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess); -void smf_sbi_send_sm_context_updated_data_in_session_deletion(smf_sess_t *sess); +void smf_sbi_send_sm_context_updated_data( + smf_sess_t *sess, ogs_sbi_session_t *session); +void smf_sbi_send_sm_context_updated_data_in_session_deletion( + smf_sess_t *sess, ogs_sbi_session_t *session); void smf_sbi_send_sm_context_update_error( ogs_sbi_session_t *session, int status, const char *title, const char *detail, diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index ad0d02d66..47e6240b3 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -604,6 +604,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) case SMF_EVT_5GSM_MESSAGE: sess = e->sess; ogs_assert(sess); + session = e->sbi.session; + ogs_assert(session); pkbuf = e->pkbuf; ogs_assert(pkbuf); @@ -631,6 +633,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) case SMF_EVT_NGAP_MESSAGE: sess = e->sess; ogs_assert(sess); + session = e->sbi.session; + ogs_assert(session); pkbuf = e->pkbuf; ogs_assert(pkbuf); ogs_assert(e->ngap.type); diff --git a/src/udm/nnrf-handler.c b/src/udm/nnrf-handler.c index 5780a4e83..a26ab5bcb 100644 --- a/src/udm/nnrf-handler.c +++ b/src/udm/nnrf-handler.c @@ -296,10 +296,6 @@ void udm_nnrf_handle_nf_discover( if (!nf_instance) { ogs_error("(NF discover) No [%s]", OpenAPI_nf_type_ToString(sbi_object->nf_type)); - ogs_sbi_server_send_error(session, - OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE, NULL, - "(NF discover) No NF", - OpenAPI_nf_type_ToString(sbi_object->nf_type)); } else { ogs_sbi_send(nf_instance, sbi_object); } diff --git a/tests/registration/dereg-test.c b/tests/registration/dereg-test.c index 54fe8eae4..5570b555f 100644 --- a/tests/registration/dereg-test.c +++ b/tests/registration/dereg-test.c @@ -1455,6 +1455,7 @@ static void test4_func(abts_case *tc, void *data) ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(&test_ue, recvbuf); + /* Send PDU session resource setup response */ sendbuf = testngap_build_pdu_session_resource_setup_response(&test_sess); ABTS_PTR_NOTNULL(tc, sendbuf);