diff --git a/configs/open5gs/amf.yaml.in b/configs/open5gs/amf.yaml.in index af9449f63..27ded0b19 100644 --- a/configs/open5gs/amf.yaml.in +++ b/configs/open5gs/amf.yaml.in @@ -290,7 +290,7 @@ pool: # # time: # -# o NF Instance Heartbeat (Default : 5 seconds) +# o NF Instance Heartbeat (Default : 10 seconds) # # o NF Instance Heartbeat (Disabled) # nf_instance: diff --git a/configs/open5gs/ausf.yaml.in b/configs/open5gs/ausf.yaml.in index 633643249..8a7c77e03 100644 --- a/configs/open5gs/ausf.yaml.in +++ b/configs/open5gs/ausf.yaml.in @@ -167,7 +167,7 @@ pool: # # time: # -# o NF Instance Heartbeat (Default : 5 seconds) +# o NF Instance Heartbeat (Default : 10 seconds) # # o NF Instance Heartbeat (Disabled) # nf_instance: diff --git a/configs/open5gs/smf.yaml.in b/configs/open5gs/smf.yaml.in index 2f5ed82a8..5d568a829 100644 --- a/configs/open5gs/smf.yaml.in +++ b/configs/open5gs/smf.yaml.in @@ -370,7 +370,7 @@ pool: # # time: # -# o NF Instance Heartbeat (Default : 5 seconds) +# o NF Instance Heartbeat (Default : 10 seconds) # # o NF Instance Heartbeat (Disabled) # nf_instance: diff --git a/configs/open5gs/udm.yaml.in b/configs/open5gs/udm.yaml.in index ef9cdb43c..8b0fad773 100644 --- a/configs/open5gs/udm.yaml.in +++ b/configs/open5gs/udm.yaml.in @@ -167,7 +167,7 @@ pool: # # time: # -# o NF Instance Heartbeat (Default : 5 seconds) +# o NF Instance Heartbeat (Default : 10 seconds) # # o NF Instance Heartbeat (Disabled) # nf_instance: diff --git a/configs/open5gs/udr.yaml.in b/configs/open5gs/udr.yaml.in index 19a65140a..c1303f2fe 100644 --- a/configs/open5gs/udr.yaml.in +++ b/configs/open5gs/udr.yaml.in @@ -169,7 +169,7 @@ pool: # # time: # -# o NF Instance Heartbeat (Default : 5 seconds) +# o NF Instance Heartbeat (Default : 10 seconds) # # o NF Instance Heartbeat (Disabled) # nf_instance: diff --git a/lib/app/ogs-config.c b/lib/app/ogs-config.c index 7093b6f55..05a27b9db 100644 --- a/lib/app/ogs-config.c +++ b/lib/app/ogs-config.c @@ -187,7 +187,7 @@ static int config_prepare(void) recalculate_pool_size(); - self.time.nf_instance.heartbeat = 5; /* 5 second */ + self.time.nf_instance.heartbeat = 10; /* 10 second */ self.time.nf_instance.validity = 3600; /* 3600 seconds = 1 hour */ self.time.subscription.validity = 86400; /* 86400 seconds = 1 day */ @@ -268,12 +268,18 @@ int ogs_config_parse() } else if (!strcmp(parameter_key, "no_pcrf")) { self.parameter.no_pcrf = ogs_yaml_iter_bool(¶meter_iter); - } else if (!strcmp(parameter_key, "no_upf")) { - self.parameter.no_upf = + } else if (!strcmp(parameter_key, "no_nrf")) { + self.parameter.no_nrf = + ogs_yaml_iter_bool(¶meter_iter); + } else if (!strcmp(parameter_key, "no_amf")) { + self.parameter.no_amf = ogs_yaml_iter_bool(¶meter_iter); } else if (!strcmp(parameter_key, "no_smf")) { self.parameter.no_smf = ogs_yaml_iter_bool(¶meter_iter); + } else if (!strcmp(parameter_key, "no_upf")) { + self.parameter.no_upf = + ogs_yaml_iter_bool(¶meter_iter); } else if (!strcmp(parameter_key, "no_ausf")) { self.parameter.no_ausf = ogs_yaml_iter_bool(¶meter_iter); diff --git a/lib/pfcp/xact.h b/lib/pfcp/xact.h index 4158617d5..eabdea505 100644 --- a/lib/pfcp/xact.h +++ b/lib/pfcp/xact.h @@ -41,10 +41,11 @@ typedef struct ogs_pfcp_xact_s { local or remote */ uint32_t xid; /**< Transaction ID */ - ogs_pfcp_node_t *node; /**< Relevant PFCP node context */ + ogs_pfcp_node_t *node; /**< Relevant PFCP node context */ - void (*cb)(ogs_pfcp_xact_t *, void *); /**< Local timer expiration handler */ - void *data; /**< Transaction Data */ + /**< Local timer expiration handler & Data*/ + void (*cb)(ogs_pfcp_xact_t *, void *); + void *data; int step; /**< Current step in the sequence. 1 : Initial @@ -61,6 +62,7 @@ typedef struct ogs_pfcp_xact_s { uint8_t holding_rcount; void *assoc_xact; /**< Associated GTP transaction */ + void *assoc_session; /**< Associated SBI session */ #define OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED 1 #define OGS_PFCP_5GC_DELETE_TRIGGER_PCF_INITIATED 2 #define OGS_PFCP_5GC_DELETE_TRIGGER_RAN_INITIATED 3 diff --git a/lib/sbi/path.c b/lib/sbi/path.c index 5a66b4117..0e44d2eac 100644 --- a/lib/sbi/path.c +++ b/lib/sbi/path.c @@ -91,7 +91,6 @@ bool ogs_sbi_discover_and_send( ogs_assert(nf_type); ogs_assert(build); - ogs_assert(sbi_object->running == false); sbi_object->running = true; sbi_object->nf_type = nf_type; diff --git a/meson.build b/meson.build index 8b4919410..66a5f424e 100644 --- a/meson.build +++ b/meson.build @@ -16,7 +16,7 @@ # along with this program. If not, see . project('open5gs', 'c', - version : '1.3.0', + version : run_command('misc/git-version-gen', '@0@/.tarball-version'.format(meson.source_root()), check : true).stdout().strip(), license : 'AGPL-3.0-or-later', meson_version : '>= 0.43.0', default_options : [ diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c index 61497f7ff..787a99cd4 100644 --- a/src/amf/gmm-handler.c +++ b/src/amf/gmm-handler.c @@ -812,10 +812,25 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, return OGS_ERROR; } + if ((ul_nas_transport->presencemask & + OGS_NAS_5GS_UL_NAS_TRANSPORT_PDU_SESSION_ID_PRESENT) == 0) { + ogs_error("[%s] No PDU session ID", amf_ue->supi); + nas_5gs_send_gmm_status( + amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION); + return OGS_ERROR; + } + + pdu_session_id = &ul_nas_transport->pdu_session_id; + if (*pdu_session_id == OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) { + ogs_error("[%s] PDU session identity is unassigned", + amf_ue->supi); + nas_5gs_send_gmm_status( + amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION); + return OGS_ERROR; + } + switch (payload_container_type->value) { case OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION: - pdu_session_id = &ul_nas_transport->pdu_session_id; - ogs_assert(pdu_session_id); nas_s_nssai = &ul_nas_transport->s_nssai; ogs_assert(nas_s_nssai); dnn = &ul_nas_transport->dnn; @@ -824,27 +839,22 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, gsm_header = (ogs_nas_5gsm_header_t *)payload_container->buffer; ogs_assert(gsm_header); - if ((ul_nas_transport->presencemask & - OGS_NAS_5GS_UL_NAS_TRANSPORT_PDU_SESSION_ID_PRESENT) == 0) { - ogs_error("[%s] No PDU session ID", amf_ue->supi); - nas_5gs_send_gmm_status( - amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION); - return OGS_ERROR; - } - - pdu_session_id = &ul_nas_transport->pdu_session_id; - if (*pdu_session_id == OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) { - ogs_error("[%s] PDU session identity is unassigned", - amf_ue->supi); - nas_5gs_send_gmm_status( - amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION); - return OGS_ERROR; - } - - sess = amf_sess_find_by_psi(amf_ue, *pdu_session_id); - if (!sess) { - sess = amf_sess_add(amf_ue, *pdu_session_id); - ogs_assert(sess); + if (gsm_header->message_type == + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST) { + sess = amf_sess_find_by_psi(amf_ue, *pdu_session_id); + if (!sess) { + sess = amf_sess_add(amf_ue, *pdu_session_id); + ogs_assert(sess); + } + } else { + sess = amf_sess_find_by_psi(amf_ue, *pdu_session_id); + if (!sess) { + ogs_error("[%s] No Session Context [%d]", + amf_ue->supi, gsm_header->message_type); + nas_5gs_send_gmm_status(amf_ue, + OGS_5GMM_CAUSE_INSUFFICIENT_USER_PLANE_RESOURCES_FOR_THE_PDU_SESSION); + return OGS_ERROR; + } } if (sess->payload_container) @@ -857,39 +867,39 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, ogs_pkbuf_put_data(sess->payload_container, payload_container->buffer, payload_container->length); - if (ul_nas_transport->presencemask & - OGS_NAS_5GS_UL_NAS_TRANSPORT_S_NSSAI_PRESENT) { - ogs_s_nssai_t s_nssai; - if (ogs_nas_parse_s_nssai(&s_nssai, nas_s_nssai) != 0) { - selected_s_nssai = - amf_find_s_nssai(&amf_ue->tai.plmn_id, &s_nssai); - } - } - - if (!selected_s_nssai) { - if (amf_ue->num_of_requested_nssai) { - selected_s_nssai = &amf_ue->requested_nssai[0]; - } - } - - if (!selected_s_nssai) { - ogs_error("No S_NSSAI : Set default S_NSSAI using AMF config"); - selected_s_nssai = &amf_self()->plmn_support[0].s_nssai[0]; - ogs_assert(selected_s_nssai); - } - - memcpy(&sess->s_nssai, selected_s_nssai, sizeof(ogs_s_nssai_t)); - - if (ul_nas_transport->presencemask & - OGS_NAS_5GS_UL_NAS_TRANSPORT_DNN_PRESENT) { - if (sess->dnn) - ogs_free(sess->dnn); - sess->dnn = ogs_strdup(dnn->value); - } - if (gsm_header->message_type == OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST) { + if (ul_nas_transport->presencemask & + OGS_NAS_5GS_UL_NAS_TRANSPORT_S_NSSAI_PRESENT) { + ogs_s_nssai_t s_nssai; + if (ogs_nas_parse_s_nssai(&s_nssai, nas_s_nssai) != 0) { + selected_s_nssai = + amf_find_s_nssai(&amf_ue->tai.plmn_id, &s_nssai); + } + } + + if (!selected_s_nssai) { + if (amf_ue->num_of_requested_nssai) { + selected_s_nssai = &amf_ue->requested_nssai[0]; + } + } + + if (!selected_s_nssai) { + ogs_error("No S_NSSAI : Set default S_NSSAI using AMF config"); + selected_s_nssai = &amf_self()->plmn_support[0].s_nssai[0]; + ogs_assert(selected_s_nssai); + } + + memcpy(&sess->s_nssai, selected_s_nssai, sizeof(ogs_s_nssai_t)); + + if (ul_nas_transport->presencemask & + OGS_NAS_5GS_UL_NAS_TRANSPORT_DNN_PRESENT) { + if (sess->dnn) + ogs_free(sess->dnn); + sess->dnn = ogs_strdup(dnn->value); + } + amf_sess_sbi_discover_and_send( OpenAPI_nf_type_SMF, sess, NULL, amf_nsmf_pdu_session_build_create_sm_context); @@ -897,8 +907,8 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, } else { if (!SESSION_CONTEXT_IN_SMF(sess)) { - ogs_error("[%s] Session Context is not in SMF [%d]", - amf_ue->supi, sess->psi); + ogs_error("[%s:%d] Session Context is not in SMF [%d]", + amf_ue->supi, sess->psi, gsm_header->message_type); nas_5gs_send_back_5gsm_message(sess, OGS_5GSM_CAUSE_PDU_SESSION_DOES_NOT_EXIST); return OGS_ERROR; diff --git a/src/amf/namf-handler.c b/src/amf/namf-handler.c index 74cdaed08..b4892f7a0 100644 --- a/src/amf/namf-handler.c +++ b/src/amf/namf-handler.c @@ -207,21 +207,22 @@ int amf_namf_callback_handle_sm_context_status( sess = amf_sess_find_by_psi(amf_ue, pdu_session_identity); if (!sess) { status = OGS_SBI_HTTP_STATUS_NOT_FOUND; - ogs_error("[%s] Cannot find session [%d]", amf_ue->supi, sess->psi); + ogs_warn("[%s] Cannot find session", amf_ue->supi); goto cleanup; } SmContextStatusNotification = recvmsg->SmContextStatusNotification; if (!SmContextStatusNotification) { status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; - ogs_error("No SmContextStatusNotification"); + ogs_error("[%s:%d] No SmContextStatusNotification", + amf_ue->supi, sess->psi); goto cleanup; } StatusInfo = SmContextStatusNotification->status_info; if (!StatusInfo) { status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; - ogs_error("No StatusInfo"); + ogs_error("[%s:%d] No StatusInfo", amf_ue->supi, sess->psi); goto cleanup; } diff --git a/src/amf/sbi-path.c b/src/amf/sbi-path.c index fa6e9873c..3dbd086e8 100644 --- a/src/amf/sbi-path.c +++ b/src/amf/sbi-path.c @@ -124,11 +124,6 @@ void amf_ue_sbi_discover_and_send( ogs_assert(nf_type); ogs_assert(amf_ue); - if (amf_ue->sbi.running == true) { - ogs_error("amf_ue_sbi_discover_and_send() is running"); - return; - } - amf_ue->sbi.nf_state_registered = amf_nf_state_registered; amf_ue->sbi.client_wait.duration = amf_timer_cfg(AMF_TIMER_SBI_CLIENT_WAIT)->duration; @@ -148,11 +143,6 @@ void amf_sess_sbi_discover_and_send( ogs_assert(sess); ogs_assert(build); - if (sess->sbi.running == true) { - ogs_error("amf_sess_sbi_discover_and_send() is running"); - return; - } - sess->sbi.nf_state_registered = amf_nf_state_registered; sess->sbi.client_wait.duration = amf_timer_cfg(AMF_TIMER_SBI_CLIENT_WAIT)->duration; diff --git a/src/ausf/sbi-path.c b/src/ausf/sbi-path.c index 0b2369b4e..a4e96c773 100644 --- a/src/ausf/sbi-path.c +++ b/src/ausf/sbi-path.c @@ -125,11 +125,6 @@ void ausf_sbi_discover_and_send( ogs_assert(nf_type); ogs_assert(build); - if (ausf_ue->sbi.running == true) { - ogs_error("ausf_sbi_discover_and_send() is running"); - return; - } - ausf_ue->sbi.nf_state_registered = ausf_nf_state_registered; ausf_ue->sbi.client_wait.duration = ausf_timer_cfg(AUSF_TIMER_SBI_CLIENT_WAIT)->duration; diff --git a/src/smf/context.c b/src/smf/context.c index 5a017fc8a..bde8f61d3 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -629,7 +629,7 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, /* Set TEID & SEID */ sess->smf_n4_teid = sess->index; - sess->smf_n4_seid = sess->index; + sess->smf_n4_seid = SMF_INDEX_TO_SEID(sess->index); /* Set APN */ ogs_cpystrn(sess->pdn.apn, apn, OGS_MAX_APN_LEN+1); @@ -1375,7 +1375,7 @@ smf_sess_t *smf_sess_find_by_teid(uint32_t teid) smf_sess_t *smf_sess_find_by_seid(uint64_t seid) { - return smf_sess_find(seid); + return smf_sess_find(SMF_SEID_TO_INDEX(seid)); } smf_sess_t *smf_sess_find_by_apn(smf_ue_t *smf_ue, char *apn) diff --git a/src/smf/context.h b/src/smf/context.h index 02cee04df..c684567ec 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -146,6 +146,9 @@ typedef struct smf_sess_s { #define SMF_5GC_SESS(__sESS) ((__sESS)->sgw_s5c_teid == 0) uint32_t sgw_s5c_teid; /* SGW-S5C-TEID is received from SGW */ +#define SMF_SEID_TO_INDEX(__iNDEX) (__iNDEX & ~0x8000000000000000) +#define SMF_INDEX_TO_SEID(__iNDEX) (__iNDEX | 0x8000000000000000) +#define SMF_EPC_SEID(__sEID) (__sEID & 0x8000000000000000) uint64_t smf_n4_seid; /* SMF SEID is dervied from INDEX */ uint64_t upf_n4_seid; /* UPF SEID is received from Peer */ diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index 4dec04283..7e3422363 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -77,7 +77,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) smf_nsmf_handle_update_sm_context(sess, sbi_message); break; CASE(OGS_SBI_RESOURCE_NAME_RELEASE) - smf_nsmf_handle_release_sm_context(sess, sbi_message); + smf_5gc_pfcp_send_session_deletion_request(sess, + OGS_PFCP_5GC_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT); break; DEFAULT smf_nsmf_handle_create_sm_context(sess, sbi_message); diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 4ea485590..dcd844dd2 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -63,6 +63,37 @@ static uint8_t gtp_cause_from_pfcp(uint8_t pfcp_cause) return OGS_GTP_CAUSE_SYSTEM_FAILURE; } +static int sbi_status_from_pfcp(uint8_t pfcp_cause) +{ + switch (pfcp_cause) { + case OGS_PFCP_CAUSE_REQUEST_ACCEPTED: + return OGS_SBI_HTTP_STATUS_OK; + case OGS_PFCP_CAUSE_REQUEST_REJECTED: + return OGS_SBI_HTTP_STATUS_FORBIDDEN; + case OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND: + return OGS_SBI_HTTP_STATUS_NOT_FOUND; + case OGS_PFCP_CAUSE_MANDATORY_IE_MISSING: + case OGS_PFCP_CAUSE_CONDITIONAL_IE_MISSING: + case OGS_PFCP_CAUSE_INVALID_LENGTH: + case OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT: + case OGS_PFCP_CAUSE_INVALID_FORWARDING_POLICY: + case OGS_PFCP_CAUSE_INVALID_F_TEID_ALLOCATION_OPTION: + case OGS_PFCP_CAUSE_RULE_CREATION_MODIFICATION_FAILURE: + case OGS_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION: + case OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE: + return OGS_SBI_HTTP_STATUS_BAD_REQUEST; + case OGS_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOCIATION: + return OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT; + case OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED: + return OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE; + case OGS_PFCP_CAUSE_SYSTEM_FAILURE: + return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR; + default: + return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR; + } + + return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR; +} void smf_n4_handle_association_setup_request( ogs_pfcp_node_t *node, ogs_pfcp_xact_t *xact, @@ -144,12 +175,16 @@ void smf_5gc_n4_handle_session_establishment_response( { ogs_pfcp_f_seid_t *up_f_seid = NULL; - ogs_assert(sess); ogs_assert(xact); ogs_assert(rsp); ogs_pfcp_xact_commit(xact); + if (!sess) { + ogs_warn("No Context"); + return; + } + if (rsp->up_f_seid.presence == 0) { ogs_error("No UP F-SEID"); return; @@ -157,7 +192,7 @@ void smf_5gc_n4_handle_session_establishment_response( if (rsp->cause.presence) { if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { - ogs_error("Cause[%d] : No Accepted", rsp->cause.u8); + ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8); return; } } else { @@ -165,6 +200,8 @@ void smf_5gc_n4_handle_session_establishment_response( return; } + ogs_assert(sess); + /* UP F-SEID */ up_f_seid = rsp->up_f_seid.data; ogs_assert(up_f_seid); @@ -186,39 +223,45 @@ void smf_5gc_n4_handle_session_modification_response( smf_sess_t *sess, ogs_pfcp_xact_t *xact, ogs_pfcp_session_modification_response_t *rsp) { + int status = 0; ogs_sbi_session_t *session = NULL; - smf_bearer_t *bearer = NULL; - ogs_assert(sess); - session = sess->sbi.session; - ogs_assert(session); ogs_assert(xact); ogs_assert(rsp); - bearer = smf_default_bearer_in_sess(sess); - ogs_assert(bearer); + session = xact->assoc_session; + ogs_assert(session); ogs_pfcp_xact_commit(xact); + status = OGS_SBI_HTTP_STATUS_OK; + + if (!sess) { + ogs_warn("No Context"); + status = OGS_SBI_HTTP_STATUS_NOT_FOUND; + } + if (rsp->cause.presence) { if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { - char *strerror = ogs_msprintf( - "PFCP Cause[%d] : No Accepted", rsp->cause.u8); - ogs_error("%s", strerror); - smf_sbi_send_sm_context_update_error(session, - OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror, - NULL, NULL, NULL); - ogs_free(strerror); - return; + ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8); + status = sbi_status_from_pfcp(rsp->cause.u8); } } else { ogs_error("No Cause"); - smf_sbi_send_sm_context_update_error(session, - OGS_SBI_HTTP_STATUS_BAD_REQUEST, - "[PFCP] No Cause", NULL, NULL, NULL); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; + } + + if (status != OGS_SBI_HTTP_STATUS_OK) { + char *strerror = ogs_msprintf( + "PFCP Cause [%d] : Not Accepted", rsp->cause.u8); + smf_sbi_send_sm_context_update_error(session, status, strerror, + NULL, NULL, NULL); + ogs_free(strerror); return; } + ogs_assert(sess); + /* UPDATE_UpCnxState - SYNC */ sess->smfUpCnxState = sess->ueUpCnxState; @@ -229,6 +272,7 @@ void smf_5gc_n4_handle_session_deletion_response( smf_sess_t *sess, ogs_pfcp_xact_t *xact, ogs_pfcp_session_deletion_response_t *rsp) { + int status = 0; int trigger; ogs_sbi_session_t *session = NULL; @@ -236,39 +280,49 @@ void smf_5gc_n4_handle_session_deletion_response( ogs_sbi_message_t sendmsg; ogs_sbi_response_t *response = NULL; - ogs_assert(sess); - session = sess->sbi.session; - ogs_assert(session); + ogs_assert(xact); ogs_assert(rsp); + session = xact->assoc_session; + ogs_assert(session); trigger = xact->trigger; ogs_assert(trigger); ogs_pfcp_xact_commit(xact); + status = OGS_SBI_HTTP_STATUS_OK; + + if (!sess) { + ogs_warn("No Context"); + status = OGS_SBI_HTTP_STATUS_NOT_FOUND; + } + if (rsp->cause.presence) { if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { - char *strerror = ogs_msprintf( - "PFCP Cause[%d] : No Accepted", rsp->cause.u8); - ogs_error("%s", strerror); - ogs_sbi_server_send_error(session, - OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL); - ogs_free(strerror); - return; + ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8); + status = sbi_status_from_pfcp(rsp->cause.u8); } } else { ogs_error("No Cause"); - ogs_sbi_server_send_error(session, - OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, - "[PFCP] No Cause", NULL); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; + } + + if (status != OGS_SBI_HTTP_STATUS_OK) { + char *strerror = ogs_msprintf( + "PFCP Cause [%d] : Not Accepted", rsp->cause.u8); + ogs_sbi_server_send_error(session, status, NULL, NULL, NULL); + ogs_free(strerror); return; } + ogs_assert(sess); + if (trigger == OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED) { smf_sbi_send_sm_context_updated_data_in_session_deletion(sess); } else { + memset(&sendmsg, 0, sizeof(sendmsg)); response = ogs_sbi_build_response( @@ -310,7 +364,7 @@ void smf_epc_n4_handle_session_establishment_response( if (rsp->cause.presence) { if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { - ogs_warn("Cause[%d] : No Accepted", rsp->cause.u8); + ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8); cause_value = gtp_cause_from_pfcp(rsp->cause.u8); } } else { @@ -378,7 +432,7 @@ void smf_epc_n4_handle_session_deletion_response( if (rsp->cause.presence) { if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { - ogs_warn("Cause[%d] : No Accepted", rsp->cause.u8); + ogs_warn("PFCP Cause[%d] : Not Accepted", rsp->cause.u8); cause_value = gtp_cause_from_pfcp(rsp->cause.u8); } } else { diff --git a/src/smf/nsmf-handler.c b/src/smf/nsmf-handler.c index f34f39b1b..cbbf85318 100644 --- a/src/smf/nsmf-handler.c +++ b/src/smf/nsmf-handler.c @@ -447,14 +447,3 @@ bool smf_nsmf_handle_update_sm_context( return true; } - -bool smf_nsmf_handle_release_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message) -{ - ogs_assert(sess); - - smf_5gc_pfcp_send_session_deletion_request( - sess, 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..0e544ddaf 100644 --- a/src/smf/nsmf-handler.h +++ b/src/smf/nsmf-handler.h @@ -30,8 +30,6 @@ bool smf_nsmf_handle_create_sm_context( smf_sess_t *sess, ogs_sbi_message_t *message); bool smf_nsmf_handle_update_sm_context( smf_sess_t *sess, ogs_sbi_message_t *message); -bool smf_nsmf_handle_release_sm_context( - smf_sess_t *sess, ogs_sbi_message_t *message); #ifdef __cplusplus } diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index 85530a18c..1a4faaf33 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -272,7 +272,26 @@ void smf_pfcp_send_heartbeat_request(ogs_pfcp_node_t *node) void smf_5gc_pfcp_send_session_establishment_request(smf_sess_t *sess) { - smf_epc_pfcp_send_session_establishment_request(sess, NULL); + int rv; + ogs_pkbuf_t *n4buf = NULL; + ogs_pfcp_header_t h; + ogs_pfcp_xact_t *xact = NULL; + + ogs_assert(sess); + + memset(&h, 0, sizeof(ogs_pfcp_header_t)); + h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE; + h.seid = sess->upf_n4_seid; + + n4buf = smf_n4_build_session_establishment_request(h.type, sess); + ogs_expect_or_return(n4buf); + + xact = ogs_pfcp_xact_local_create( + sess->pfcp_node, &h, n4buf, timeout, sess); + ogs_expect_or_return(xact); + + rv = ogs_pfcp_xact_commit(xact); + ogs_expect(rv == OGS_OK); } void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess) @@ -295,6 +314,7 @@ void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess) xact = ogs_pfcp_xact_local_create( sess->pfcp_node, &h, n4buf, timeout, bearer); ogs_expect_or_return(xact); + xact->assoc_session = sess->sbi.session; rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -320,6 +340,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, timeout, sess); ogs_expect_or_return(xact); + xact->assoc_session = sess->sbi.session; xact->trigger = trigger; rv = ogs_pfcp_xact_commit(xact); diff --git a/src/smf/pfcp-sm.c b/src/smf/pfcp-sm.c index b2b114e41..952de6cdc 100644 --- a/src/smf/pfcp-sm.c +++ b/src/smf/pfcp-sm.c @@ -207,29 +207,47 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) &message->pfcp_association_setup_response); break; case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE: - if (SMF_5GC_SESS(sess)) - smf_5gc_n4_handle_session_establishment_response( - sess, xact, &message->pfcp_session_establishment_response); - else + if (!message->h.seid_presence) { + ogs_error("No SEID"); + break; + } + + if (SMF_EPC_SEID(message->h.seid)) smf_epc_n4_handle_session_establishment_response( sess, xact, &message->pfcp_session_establishment_response); - break; - case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE: - if (SMF_5GC_SESS(sess)) - smf_5gc_n4_handle_session_modification_response( - sess, xact, &message->pfcp_session_modification_response); else + smf_5gc_n4_handle_session_establishment_response( + sess, xact, &message->pfcp_session_establishment_response); + break; + + case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE: + if (!message->h.seid_presence) { + ogs_error("No SEID"); + break; + } + + if (SMF_EPC_SEID(message->h.seid)) smf_epc_n4_handle_session_modification_response( sess, xact, &message->pfcp_session_modification_response); - break; - case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE: - if (SMF_5GC_SESS(sess)) - smf_5gc_n4_handle_session_deletion_response( - sess, xact, &message->pfcp_session_deletion_response); else + smf_5gc_n4_handle_session_modification_response( + sess, xact, &message->pfcp_session_modification_response); + break; + + case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE: + if (!message->h.seid_presence) { + ogs_error("No SEID"); + break; + } + + if (SMF_EPC_SEID(message->h.seid)) smf_epc_n4_handle_session_deletion_response( sess, xact, &message->pfcp_session_deletion_response); + else + smf_5gc_n4_handle_session_deletion_response( + sess, xact, &message->pfcp_session_deletion_response); break; + default: ogs_error("Not implemented PFCP message type[%d]", message->h.type); diff --git a/src/smf/sbi-path.c b/src/smf/sbi-path.c index fae1293fd..0ed586732 100644 --- a/src/smf/sbi-path.c +++ b/src/smf/sbi-path.c @@ -132,11 +132,6 @@ void smf_sbi_discover_and_send( smf_ue = sess->smf_ue; ogs_assert(smf_ue); - if (sess->sbi.running == true) { - ogs_error("smf_sbi_discover_and_send() is running"); - return; - } - sess->sbi.nf_state_registered = smf_nf_state_registered; sess->sbi.client_wait.duration = smf_timer_cfg(SMF_TIMER_SBI_CLIENT_WAIT)->duration; diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index 0e72aa4d5..d3018aa1b 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -341,12 +341,10 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) sbi_message.h.resource.component[1]); if (!sess) { - ogs_error("Not found [%s]", - sbi_message.h.resource.component[1]); + ogs_warn("Not found [%s]", sbi_message.h.uri); smf_sbi_send_sm_context_update_error(session, OGS_SBI_HTTP_STATUS_NOT_FOUND, "Not found", - sbi_message.h.resource.component[1], - NULL, NULL); + sbi_message.h.uri, NULL, NULL); } break; diff --git a/src/udm/sbi-path.c b/src/udm/sbi-path.c index 7e582c80a..29ce90a7b 100644 --- a/src/udm/sbi-path.c +++ b/src/udm/sbi-path.c @@ -135,11 +135,6 @@ void udm_sbi_discover_and_send( ogs_assert(nf_type); ogs_assert(build); - if (udm_ue->sbi.running == true) { - ogs_error("udm_sbi_discover_and_send() is running"); - return; - } - udm_ue->sbi.nf_state_registered = udm_nf_state_registered; udm_ue->sbi.client_wait.duration = udm_timer_cfg(UDM_TIMER_SBI_CLIENT_WAIT)->duration; diff --git a/src/upf/n4-handler.c b/src/upf/n4-handler.c index f72d1d81d..333fe26a6 100644 --- a/src/upf/n4-handler.c +++ b/src/upf/n4-handler.c @@ -716,7 +716,7 @@ void upf_n4_handle_session_deletion_request( if (!sess) { ogs_warn("No Context"); ogs_pfcp_send_error_message(xact, 0, - OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE, + OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE, OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0); return; } diff --git a/tests/registration/dereg-test.c b/tests/registration/dereg-test.c index 1e4b9cda1..e1b42188c 100644 --- a/tests/registration/dereg-test.c +++ b/tests/registration/dereg-test.c @@ -377,11 +377,403 @@ static void test1_func(abts_case *tc, void *data) test_ue_remove(&test_ue); } +static void test2_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *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; + int msgindex = 0; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t test_ue; + test_sess_t test_sess; + + uint8_t tmp[OGS_MAX_SDU_LEN]; + + const char *_k_string = "70d49a71dd1a2b806a25abe0ef749f1e"; + uint8_t k[OGS_KEY_LEN]; + const char *_opc_string = "6f1bf53d624b3a43af6592854e2444c7"; + uint8_t opc[OGS_KEY_LEN]; + + mongoc_collection_t *collection = NULL; + bson_t *doc = NULL; + int64_t count = 0; + bson_error_t error; + const char *json = + "{" + "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, " + "\"imsi\" : \"901700000021309\"," + "\"ambr\" : { " + "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1024000\" } " + "}," + "\"pdn\" : [" + "{" + "\"apn\" : \"internet\", " + "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c7\" }, " + "\"ambr\" : {" + "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1024000\" } " + "}," + "\"qos\" : { " + "\"qci\" : 9, " + "\"arp\" : { " + "\"priority_level\" : 8," + "\"pre_emption_vulnerability\" : 1, " + "\"pre_emption_capability\" : 1" + "} " + "}, " + "\"type\" : 2" + "}" + "]," + "\"security\" : { " + "\"k\" : \"70d49a71dd1a2b806a25abe0ef749f1e\", " + "\"opc\" : \"6f1bf53d624b3a43af6592854e2444c7\", " + "\"amf\" : \"8000\", " + "\"sqn\" : { \"$numberLong\" : \"25235952177090\" } " + "}, " + "\"subscribed_rau_tau_timer\" : 12," + "\"network_access_mode\" : 2, " + "\"subscriber_status\" : 0, " + "\"access_restriction_data\" : 32, " + "\"__v\" : 0 " + "}"; + + /* Setup Test UE & Session Context */ + memset(&test_ue, 0, sizeof(test_ue)); + memset(&test_sess, 0, sizeof(test_sess)); + test_sess.test_ue = &test_ue; + test_ue.sess = &test_sess; + + test_ue.nas.registration.type = 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; + + 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; + ogs_nas_from_plmn_id(&mobile_identity_suci.nas_plmn_id, + &test_self()->tai.plmn_id); + mobile_identity_suci.routing_indicator1 = 0; + mobile_identity_suci.routing_indicator2 = 0xf; + mobile_identity_suci.routing_indicator3 = 0xf; + mobile_identity_suci.routing_indicator4 = 0xf; + mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0; + mobile_identity_suci.scheme_output[1] = 0; + mobile_identity_suci.scheme_output[2] = 0x20; + mobile_identity_suci.scheme_output[3] = 0x31; + mobile_identity_suci.scheme_output[4] = 0x90; + + test_ue_set_mobile_identity_suci(&test_ue, &mobile_identity_suci, 13); + + memset(&test_ue.mobile_identity_imeisv, 0, + sizeof(ogs_nas_mobile_identity_imeisv_t)); + test_ue.mobile_identity_imeisv.type = OGS_NAS_5GS_MOBILE_IDENTITY_IMEISV; + test_ue.mobile_identity_imeisv.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN; + test_ue.mobile_identity_imeisv.digit1 = 8; + test_ue.mobile_identity_imeisv.digit2 = 6; + test_ue.mobile_identity_imeisv.digit3 = 6; + test_ue.mobile_identity_imeisv.digit4 = 5; + test_ue.mobile_identity_imeisv.digit5 = 0; + test_ue.mobile_identity_imeisv.digit6 = 7; + test_ue.mobile_identity_imeisv.digit7 = 0; + test_ue.mobile_identity_imeisv.digit8 = 4; + test_ue.mobile_identity_imeisv.digit9 = 0; + test_ue.mobile_identity_imeisv.digit10 = 0; + test_ue.mobile_identity_imeisv.digit11 = 4; + test_ue.mobile_identity_imeisv.digit12 = 0; + test_ue.mobile_identity_imeisv.digit13 = 5; + test_ue.mobile_identity_imeisv.digit14 = 3; + test_ue.mobile_identity_imeisv.digit15 = 0; + test_ue.mobile_identity_imeisv.digit16 = 1; + test_ue.mobile_identity_imeisv.digit17 = 0xf; + + test_ue.nas.access_type = OGS_ACCESS_TYPE_3GPP; + test_ue.abba_len = 2; + + OGS_HEX(_k_string, strlen(_k_string), test_ue.k); + OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); + + test_sess.psi = 5; + test_sess.pti = 1; + test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; + test_sess.dnn = (char *)"internet"; + + memset(&test_sess.gnb_n3_ip, 0, sizeof(test_sess.gnb_n3_ip)); + test_sess.gnb_n3_ip.ipv4 = true; + test_sess.gnb_n3_ip.addr = inet_addr("127.0.0.5"); + test_sess.gnb_n3_teid = 0; + + /* gNB connects to AMF */ + ngap = testgnb_ngap_client("127.0.0.2"); + ABTS_PTR_NOTNULL(tc, ngap); + + /* gNB connects to UPF */ + gtpu = testgnb_gtpu_server("127.0.0.5"); + 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 */ + collection = mongoc_client_get_collection( + ogs_mongoc()->client, ogs_mongoc()->name, "subscribers"); + ABTS_PTR_NOTNULL(tc, collection); + doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi)); + ABTS_PTR_NOTNULL(tc, doc); + + count = mongoc_collection_count ( + collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); + if (count) { + ABTS_TRUE(tc, mongoc_collection_remove(collection, + MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) + } + bson_destroy(doc); + + doc = bson_new_from_json((const uint8_t *)json, -1, &error);; + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_insert(collection, + MONGOC_INSERT_NONE, doc, NULL, &error)); + bson_destroy(doc); + + doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi)); + ABTS_PTR_NOTNULL(tc, doc); + do { + count = mongoc_collection_count ( + collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); + } while (count == 0); + bson_destroy(doc); + + /* Send Registration request */ + gmmbuf = testgmm_build_registration_request(&test_ue, NULL); + ABTS_PTR_NOTNULL(tc, gmmbuf); + + test_ue.registration_request_type.requested_nssai = 1; + test_ue.registration_request_type.last_visited_registered_tai = 1; + test_ue.registration_request_type.ue_usage_setting = 1; + nasbuf = testgmm_build_registration_request(&test_ue, NULL); + ABTS_PTR_NOTNULL(tc, nasbuf); + + 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); + + /* 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 Initial context setup request */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(&test_ue, recvbuf); + + /* Send UE radio capability info indication */ + 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 Initial context setup response */ + sendbuf = testngap_build_initial_context_setup_response(&test_ue, NULL); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(100); + + /* 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 Configuration update complete */ + gmmbuf = testgmm_build_configuration_update_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); + + /* Send PDU session establishment request */ + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(&test_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 PDU session establishment accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(&test_ue, recvbuf); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_build_ping(&sendbuf, &test_sess, "10.45.0.1"); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testgnb_gtpu_send(gtpu, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send PDU session resource setup response */ + ogs_msleep(100); + + sendbuf = testngap_build_pdu_session_resource_setup_response(&test_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_build_ping(&sendbuf, &test_sess, "10.45.0.1"); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + rv = testgnb_gtpu_send(gtpu, 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); + + ogs_msleep(100); + + /* Send PDU Session release request */ + gsmbuf = testgsm_build_pdu_session_release_request(&test_sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(&test_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 PDU session release command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(&test_ue, recvbuf); + + /* Send PDU session resource release response */ + sendbuf = testngap_build_pdu_session_resource_release_response(&test_sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(100); + + /* Send PDU session resource release complete */ + gsmbuf = testgsm_build_pdu_session_release_complete(&test_sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(&test_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); + + ogs_msleep(100); + + /* Send De-registration request */ + gmmbuf = testgmm_build_de_registration_request(&test_ue, 1); + 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 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); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(100); + + /********** Remove Subscriber in Database */ + doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi)); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_remove(collection, + MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) + bson_destroy(doc); + + mongoc_collection_destroy(collection); + + /* 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) abts_run_test(suite, test1_func, NULL); + abts_run_test(suite, test2_func, NULL); return suite; } diff --git a/tests/registration/guti-test.c b/tests/registration/guti-test.c index 680e27c40..17c6392b6 100644 --- a/tests/registration/guti-test.c +++ b/tests/registration/guti-test.c @@ -539,372 +539,11 @@ static void test1_func(abts_case *tc, void *data) test_ue_remove(&test_ue); } -static void test2_func(abts_case *tc, void *data) -{ - int rv; - ogs_socknode_t *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; - int msgindex = 0; - - ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; - test_ue_t test_ue; - test_sess_t test_sess; - - uint8_t tmp[OGS_MAX_SDU_LEN]; - - const char *_k_string = "70d49a71dd1a2b806a25abe0ef749f1e"; - uint8_t k[OGS_KEY_LEN]; - const char *_opc_string = "6f1bf53d624b3a43af6592854e2444c7"; - uint8_t opc[OGS_KEY_LEN]; - - mongoc_collection_t *collection = NULL; - bson_t *doc = NULL; - int64_t count = 0; - bson_error_t error; - const char *json = - "{" - "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, " - "\"imsi\" : \"901700000021309\"," - "\"ambr\" : { " - "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " - "\"downlink\" : { \"$numberLong\" : \"1024000\" } " - "}," - "\"pdn\" : [" - "{" - "\"apn\" : \"internet\", " - "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c7\" }, " - "\"ambr\" : {" - "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " - "\"downlink\" : { \"$numberLong\" : \"1024000\" } " - "}," - "\"qos\" : { " - "\"qci\" : 9, " - "\"arp\" : { " - "\"priority_level\" : 8," - "\"pre_emption_vulnerability\" : 1, " - "\"pre_emption_capability\" : 1" - "} " - "}, " - "\"type\" : 2" - "}" - "]," - "\"security\" : { " - "\"k\" : \"70d49a71dd1a2b806a25abe0ef749f1e\", " - "\"opc\" : \"6f1bf53d624b3a43af6592854e2444c7\", " - "\"amf\" : \"8000\", " - "\"sqn\" : { \"$numberLong\" : \"25235952177090\" } " - "}, " - "\"subscribed_rau_tau_timer\" : 12," - "\"network_access_mode\" : 2, " - "\"subscriber_status\" : 0, " - "\"access_restriction_data\" : 32, " - "\"__v\" : 0 " - "}"; - - /* Setup Test UE & Session Context */ - memset(&test_ue, 0, sizeof(test_ue)); - memset(&test_sess, 0, sizeof(test_sess)); - test_sess.test_ue = &test_ue; - test_ue.sess = &test_sess; - - test_ue.nas.registration.type = 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; - - 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; - ogs_nas_from_plmn_id(&mobile_identity_suci.nas_plmn_id, - &test_self()->tai.plmn_id); - mobile_identity_suci.routing_indicator1 = 0; - mobile_identity_suci.routing_indicator2 = 0xf; - mobile_identity_suci.routing_indicator3 = 0xf; - mobile_identity_suci.routing_indicator4 = 0xf; - mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; - mobile_identity_suci.home_network_pki_value = 0; - mobile_identity_suci.scheme_output[0] = 0; - mobile_identity_suci.scheme_output[1] = 0; - mobile_identity_suci.scheme_output[2] = 0x20; - mobile_identity_suci.scheme_output[3] = 0x31; - mobile_identity_suci.scheme_output[4] = 0x90; - - test_ue_set_mobile_identity_suci(&test_ue, &mobile_identity_suci, 13); - - memset(&test_ue.mobile_identity_imeisv, 0, - sizeof(ogs_nas_mobile_identity_imeisv_t)); - test_ue.mobile_identity_imeisv.type = OGS_NAS_5GS_MOBILE_IDENTITY_IMEISV; - test_ue.mobile_identity_imeisv.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN; - test_ue.mobile_identity_imeisv.digit1 = 8; - test_ue.mobile_identity_imeisv.digit2 = 6; - test_ue.mobile_identity_imeisv.digit3 = 6; - test_ue.mobile_identity_imeisv.digit4 = 5; - test_ue.mobile_identity_imeisv.digit5 = 0; - test_ue.mobile_identity_imeisv.digit6 = 7; - test_ue.mobile_identity_imeisv.digit7 = 0; - test_ue.mobile_identity_imeisv.digit8 = 4; - test_ue.mobile_identity_imeisv.digit9 = 0; - test_ue.mobile_identity_imeisv.digit10 = 0; - test_ue.mobile_identity_imeisv.digit11 = 4; - test_ue.mobile_identity_imeisv.digit12 = 0; - test_ue.mobile_identity_imeisv.digit13 = 5; - test_ue.mobile_identity_imeisv.digit14 = 3; - test_ue.mobile_identity_imeisv.digit15 = 0; - test_ue.mobile_identity_imeisv.digit16 = 1; - test_ue.mobile_identity_imeisv.digit17 = 0xf; - - test_ue.nas.access_type = OGS_ACCESS_TYPE_3GPP; - test_ue.abba_len = 2; - - OGS_HEX(_k_string, strlen(_k_string), test_ue.k); - OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - - test_sess.psi = 5; - test_sess.pti = 1; - test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; - test_sess.dnn = (char *)"internet"; - - memset(&test_sess.gnb_n3_ip, 0, sizeof(test_sess.gnb_n3_ip)); - test_sess.gnb_n3_ip.ipv4 = true; - test_sess.gnb_n3_ip.addr = inet_addr("127.0.0.5"); - test_sess.gnb_n3_teid = 0; - - /* gNB connects to AMF */ - ngap = testgnb_ngap_client("127.0.0.2"); - ABTS_PTR_NOTNULL(tc, ngap); - - /* gNB connects to UPF */ - gtpu = testgnb_gtpu_server("127.0.0.5"); - ABTS_PTR_NOTNULL(tc, gtpu); - - /* Send NG-Setup Reqeust */ - sendbuf = testngap_build_ng_setup_request(0x4000, 22); - 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 */ - collection = mongoc_client_get_collection( - ogs_mongoc()->client, ogs_mongoc()->name, "subscribers"); - ABTS_PTR_NOTNULL(tc, collection); - doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi)); - ABTS_PTR_NOTNULL(tc, doc); - - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); - if (count) { - ABTS_TRUE(tc, mongoc_collection_remove(collection, - MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) - } - bson_destroy(doc); - - doc = bson_new_from_json((const uint8_t *)json, -1, &error);; - ABTS_PTR_NOTNULL(tc, doc); - ABTS_TRUE(tc, mongoc_collection_insert(collection, - MONGOC_INSERT_NONE, doc, NULL, &error)); - bson_destroy(doc); - - doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi)); - ABTS_PTR_NOTNULL(tc, doc); - do { - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); - } while (count == 0); - bson_destroy(doc); - - /* Send Registration request */ - test_ue.registration_request_type.guti = 1; - gmmbuf = testgmm_build_registration_request(&test_ue, NULL); - ABTS_PTR_NOTNULL(tc, gmmbuf); - - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 1; - nasbuf = testgmm_build_registration_request(&test_ue, NULL); - ABTS_PTR_NOTNULL(tc, nasbuf); - - 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); - - /* Receive Identity request */ - recvbuf = testgnb_ngap_read(ngap); - ABTS_PTR_NOTNULL(tc, recvbuf); - testngap_recv(&test_ue, recvbuf); - - /* Send Identity response */ - gmmbuf = testgmm_build_identity_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 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 Initial context setup request */ - recvbuf = testgnb_ngap_read(ngap); - ABTS_PTR_NOTNULL(tc, recvbuf); - testngap_recv(&test_ue, recvbuf); - - /* Send UE radio capability info indication */ - 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 Initial context setup response */ - sendbuf = testngap_build_initial_context_setup_response(&test_ue, NULL); - 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 Configuration update complete */ - gmmbuf = testgmm_build_configuration_update_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); - - /* Send PDU session establishment request */ - gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); - ABTS_PTR_NOTNULL(tc, gsmbuf); - gmmbuf = testgmm_build_ul_nas_transport(&test_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 PDU session establishment accept */ - recvbuf = testgnb_ngap_read(ngap); - ABTS_PTR_NOTNULL(tc, recvbuf); - testngap_recv(&test_ue, recvbuf); - - ogs_msleep(100); - - /* Send PDU session resource setup response */ - sendbuf = testngap_build_pdu_session_resource_setup_response(&test_sess); - ABTS_PTR_NOTNULL(tc, sendbuf); - rv = testgnb_ngap_send(ngap, sendbuf); - ABTS_INT_EQUAL(tc, OGS_OK, rv); - - ogs_msleep(100); - - /* Send PDU Session release request */ - gsmbuf = testgsm_build_pdu_session_release_request(&test_sess); - ABTS_PTR_NOTNULL(tc, gsmbuf); - gmmbuf = testgmm_build_ul_nas_transport(&test_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 PDU session release command */ - recvbuf = testgnb_ngap_read(ngap); - ABTS_PTR_NOTNULL(tc, recvbuf); - testngap_recv(&test_ue, recvbuf); - - /* Send PDU session resource release response */ - sendbuf = testngap_build_pdu_session_resource_release_response(&test_sess); - ABTS_PTR_NOTNULL(tc, sendbuf); - rv = testgnb_ngap_send(ngap, sendbuf); - ABTS_INT_EQUAL(tc, OGS_OK, rv); - - ogs_msleep(100); - - /* Send PDU session resource release complete */ - gsmbuf = testgsm_build_pdu_session_release_complete(&test_sess); - ABTS_PTR_NOTNULL(tc, gsmbuf); - gmmbuf = testgmm_build_ul_nas_transport(&test_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); - - ogs_msleep(100); - - /********** Remove Subscriber in Database */ - doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi)); - ABTS_PTR_NOTNULL(tc, doc); - ABTS_TRUE(tc, mongoc_collection_remove(collection, - MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) - bson_destroy(doc); - - mongoc_collection_destroy(collection); - - /* 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_guti(abts_suite *suite) { suite = ADD_SUITE(suite) abts_run_test(suite, test1_func, NULL); - abts_run_test(suite, test2_func, NULL); return suite; }