mirror of
https://github.com/open5gs/open5gs.git
synced 2025-10-22 23:31:57 +00:00
Merge branch 'main' into home-routed
This commit is contained in:
@@ -161,7 +161,7 @@ ogs_sbi_client_t *ogs_sbi_client_add(
|
||||
curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, client);
|
||||
curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(multi, CURLMOPT_TIMERDATA, client);
|
||||
#ifdef CURLMOPT_MAX_CONCURRENT_STREAMS
|
||||
#if CURL_AT_LEAST_VERSION(7,67,0)
|
||||
curl_multi_setopt(multi, CURLMOPT_MAX_CONCURRENT_STREAMS,
|
||||
ogs_app()->pool.stream);
|
||||
#endif
|
||||
|
@@ -3210,6 +3210,11 @@ static int parse_multipart(
|
||||
ogs_assert(message);
|
||||
ogs_assert(http);
|
||||
|
||||
if (!http->content) {
|
||||
ogs_error("HTTP content NULL [%d]", (int)http->content_length);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
settings.on_header_field = &on_header_field;
|
||||
settings.on_header_value = &on_header_value;
|
||||
|
@@ -332,10 +332,33 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &sbi_message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &sbi_message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -4054,6 +4054,7 @@ void ngap_handle_handover_notification(
|
||||
{
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
int i, r;
|
||||
int xact_count;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
amf_sess_t *sess = NULL;
|
||||
@@ -4213,15 +4214,14 @@ void ngap_handle_handover_notification(
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
|
||||
/* Save the number of ongoing SMF transactions before processing sessions */
|
||||
xact_count = amf_sess_xact_count(amf_ue);
|
||||
|
||||
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
||||
if (!SESSION_CONTEXT_IN_SMF(sess)) {
|
||||
ogs_error("Session Context is not in SMF [%d]", sess->psi);
|
||||
r = ngap_send_error_indication2(source_ue,
|
||||
NGAP_Cause_PR_radioNetwork,
|
||||
NGAP_CauseRadioNetwork_partial_handover);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
return;
|
||||
/* Warn if this UE session is not handled by SMF and skip it */
|
||||
ogs_warn("Session Context is not in SMF [%d]", sess->psi);
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
@@ -4234,6 +4234,19 @@ void ngap_handle_handover_notification(
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no SMF sessions were processed (transaction count unchanged),
|
||||
* send partial-handover error
|
||||
*/
|
||||
if (xact_count == amf_sess_xact_count(amf_ue)) {
|
||||
ogs_error("No SMF session were processed [%d]", sess->psi);
|
||||
r = ngap_send_error_indication2(source_ue,
|
||||
NGAP_Cause_PR_radioNetwork,
|
||||
NGAP_CauseRadioNetwork_partial_handover);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void ngap_handle_ran_configuration_update(
|
||||
|
@@ -215,10 +215,33 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -234,10 +234,33 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -221,10 +221,33 @@ void nssf_state_operational(ogs_fsm_t *s, nssf_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -381,10 +381,33 @@ void pcf_state_operational(ogs_fsm_t *s, pcf_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -167,10 +167,33 @@ void scp_state_operational(ogs_fsm_t *s, scp_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -241,11 +241,32 @@ void sepp_state_operational(ogs_fsm_t *s, sepp_event_t *e)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
old_state = OGS_FSM_STATE(&nf_instance->sm);
|
||||
ogs_assert(old_state);
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
if (old_state) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
/*
|
||||
* The SEPP on the H-PLMN should send a n32c-handshake message
|
||||
|
@@ -836,10 +836,33 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &sbi_message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &sbi_message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -288,10 +288,33 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -225,10 +225,33 @@ void udr_state_operational(ogs_fsm_t *s, udr_event_t *e)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
nf_instance = e->h.sbi.data;
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
/*
|
||||
* Guard against dispatching to an FSM that may have been finalized
|
||||
* by an asynchronous shutdown triggered by SIGTERM.
|
||||
*
|
||||
* In init.c’s event_termination(), which can be invoked asynchronously
|
||||
* when the process receives SIGTERM, we iterate over all NF instances:
|
||||
* ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||
* ogs_sbi_nf_fsm_fini(nf_instance);
|
||||
* and call ogs_fsm_fini() on each instance’s FSM. That finalizes the FSM
|
||||
* and its state is reset to zero.
|
||||
*
|
||||
* After event_termination(), any incoming SBI response—such as an NRF
|
||||
* client callback arriving after deregistration—would otherwise be
|
||||
* dispatched into a dead FSM and trigger an assertion failure.
|
||||
*
|
||||
* To avoid this, we check OGS_FSM_STATE(&nf_instance->sm):
|
||||
* - If non-zero, the FSM is still active and can safely handle the event.
|
||||
* - If zero, the FSM has already been finalized by event_termination(),
|
||||
* so we log and drop the event to allow graceful shutdown.
|
||||
*/
|
||||
if (OGS_FSM_STATE(&nf_instance->sm)) {
|
||||
e->h.sbi.message = &message;
|
||||
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||
} else
|
||||
ogs_error("NF instance FSM has been finalized");
|
||||
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
|
@@ -2714,6 +2714,361 @@ static void indirect_cancel_func(abts_case *tc, void *data)
|
||||
test_ue_remove(test_ue);
|
||||
}
|
||||
|
||||
static void partial_handover_func(abts_case *tc, void *data)
|
||||
{
|
||||
int rv;
|
||||
ogs_socknode_t *ngap1, *ngap2;
|
||||
ogs_socknode_t *gtpu1, *gtpu2;
|
||||
ogs_pkbuf_t *gmmbuf;
|
||||
ogs_pkbuf_t *gsmbuf;
|
||||
ogs_pkbuf_t *nasbuf;
|
||||
ogs_pkbuf_t *sendbuf;
|
||||
ogs_pkbuf_t *recvbuf;
|
||||
ogs_pkbuf_t *pkbuf;
|
||||
ogs_ngap_message_t message;
|
||||
int i;
|
||||
|
||||
uint8_t tmp[OGS_HUGE_LEN];
|
||||
char *_gtp_payload = "34ff0024"
|
||||
"0000000100000085 010002004500001c 0c0b000040015a7a 0a2d00010a2d0002"
|
||||
"00000964cd7c291f";
|
||||
|
||||
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
|
||||
test_ue_t *test_ue = NULL;
|
||||
test_sess_t *sess = NULL;
|
||||
test_bearer_t *qos_flow = NULL;
|
||||
|
||||
uint64_t ran_ue_ngap_id;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
bson_t *doc = NULL;
|
||||
|
||||
/* Setup Test UE & Session Context */
|
||||
memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
|
||||
|
||||
mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
|
||||
mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
|
||||
mobile_identity_suci.routing_indicator1 = 0;
|
||||
mobile_identity_suci.routing_indicator2 = 0xf;
|
||||
mobile_identity_suci.routing_indicator3 = 0xf;
|
||||
mobile_identity_suci.routing_indicator4 = 0xf;
|
||||
mobile_identity_suci.protection_scheme_id = OGS_PROTECTION_SCHEME_NULL;
|
||||
mobile_identity_suci.home_network_pki_value = 0;
|
||||
|
||||
test_ue = test_ue_add_by_suci(&mobile_identity_suci, "0000203190");
|
||||
ogs_assert(test_ue);
|
||||
|
||||
test_ue->nr_cgi.cell_id = 0x40001;
|
||||
|
||||
test_ue->nas.registration.tsc = 0;
|
||||
test_ue->nas.registration.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
|
||||
test_ue->nas.registration.follow_on_request = 1;
|
||||
test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL;
|
||||
|
||||
test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
|
||||
test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca";
|
||||
|
||||
/* Two gNB connects to AMF */
|
||||
ngap1 = testngap_client(1, AF_INET);
|
||||
ABTS_PTR_NOTNULL(tc, ngap1);
|
||||
|
||||
ngap2 = testngap_client(1, AF_INET);
|
||||
ABTS_PTR_NOTNULL(tc, ngap2);
|
||||
|
||||
/* Two gNB connects to UPF */
|
||||
gtpu1 = test_gtpu_server(1, AF_INET);
|
||||
ABTS_PTR_NOTNULL(tc, gtpu1);
|
||||
|
||||
gtpu2 = test_gtpu_server(2, AF_INET);
|
||||
ABTS_PTR_NOTNULL(tc, gtpu2);
|
||||
|
||||
/* NG-Setup Reqeust/Response for Source gNB */
|
||||
sendbuf = testngap_build_ng_setup_request(0x4000, 28);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/* NG-Setup Reqeust/Response for Target gNB */
|
||||
sendbuf = testngap_build_ng_setup_request(0x4001, 28);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap2, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
recvbuf = testgnb_ngap_read(ngap2);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/********** Insert Subscriber in Database */
|
||||
doc = test_db_new_simple(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, doc);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc));
|
||||
|
||||
/* Send Registration request */
|
||||
test_ue->registration_request_param.guti = 1;
|
||||
gmmbuf = testgmm_build_registration_request(test_ue, NULL, false, false);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
|
||||
test_ue->registration_request_param.gmm_capability = 1;
|
||||
test_ue->registration_request_param.s1_ue_network_capability = 1;
|
||||
test_ue->registration_request_param.requested_nssai = 1;
|
||||
test_ue->registration_request_param.last_visited_registered_tai = 1;
|
||||
test_ue->registration_request_param.ue_usage_setting = 1;
|
||||
nasbuf = testgmm_build_registration_request(test_ue, NULL, false, false);
|
||||
ABTS_PTR_NOTNULL(tc, nasbuf);
|
||||
|
||||
sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf,
|
||||
NGAP_RRCEstablishmentCause_mo_Signalling, false, true);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Identity request */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
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(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Authentication request */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
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(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Security mode command */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
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(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive InitialContextSetupRequest +
|
||||
* Registration accept */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
ABTS_INT_EQUAL(tc,
|
||||
NGAP_ProcedureCode_id_InitialContextSetup,
|
||||
test_ue->ngap_procedure_code);
|
||||
|
||||
/* Send UERadioCapabilityInfoIndication */
|
||||
sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Send InitialContextSetupResponse */
|
||||
sendbuf = testngap_build_initial_context_setup_response(test_ue, false);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, 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(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Configuration update command */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
|
||||
/* Send PDU session establishment request */
|
||||
sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5);
|
||||
ogs_assert(sess);
|
||||
|
||||
sess->ul_nas_transport_param.request_type =
|
||||
OGS_NAS_5GS_REQUEST_TYPE_INITIAL;
|
||||
sess->ul_nas_transport_param.dnn = 1;
|
||||
sess->ul_nas_transport_param.s_nssai = 1;
|
||||
|
||||
sess->pdu_session_establishment_param.ssc_mode = 1;
|
||||
sess->pdu_session_establishment_param.epco = 1;
|
||||
|
||||
gsmbuf = testgsm_build_pdu_session_establishment_request(sess);
|
||||
ABTS_PTR_NOTNULL(tc, gsmbuf);
|
||||
gmmbuf = testgmm_build_ul_nas_transport(sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive PDUSessionResourceSetupRequest +
|
||||
* DL NAS transport +
|
||||
* PDU session establishment accept */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
ABTS_INT_EQUAL(tc,
|
||||
NGAP_ProcedureCode_id_PDUSessionResourceSetup,
|
||||
test_ue->ngap_procedure_code);
|
||||
|
||||
/* Send PDUSessionResourceSetupResponse */
|
||||
sendbuf = testngap_sess_build_pdu_session_resource_setup_response(sess);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Send PDU session establishment request */
|
||||
sess = test_sess_add_by_dnn_and_psi(test_ue, "ims", 6);
|
||||
ogs_assert(sess);
|
||||
|
||||
sess->ul_nas_transport_param.request_type =
|
||||
OGS_NAS_5GS_REQUEST_TYPE_INITIAL;
|
||||
sess->ul_nas_transport_param.dnn = 1;
|
||||
sess->ul_nas_transport_param.s_nssai = 1;
|
||||
|
||||
sess->pdu_session_establishment_param.ssc_mode = 1;
|
||||
sess->pdu_session_establishment_param.epco = 1;
|
||||
|
||||
gsmbuf = testgsm_build_pdu_session_establishment_request(sess);
|
||||
ABTS_PTR_NOTNULL(tc, gsmbuf);
|
||||
gmmbuf = testgmm_build_ul_nas_transport(sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive 5GMM status */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
ABTS_INT_EQUAL(tc,
|
||||
NGAP_ProcedureCode_id_DownlinkNASTransport,
|
||||
test_ue->ngap_procedure_code);
|
||||
|
||||
/* Remove ims session in test context */
|
||||
test_sess_remove(sess);
|
||||
|
||||
/* Send HandoverRequired */
|
||||
sendbuf = testngap_build_handover_required(
|
||||
test_ue, NGAP_HandoverType_intra5gs,
|
||||
0x4001, 28,
|
||||
NGAP_Cause_PR_radioNetwork,
|
||||
NGAP_CauseRadioNetwork_handover_desirable_for_radio_reason,
|
||||
false);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive HandoverRequest */
|
||||
recvbuf = testgnb_ngap_read(ngap2);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
ABTS_INT_EQUAL(tc,
|
||||
NGAP_ProcedureCode_id_HandoverResourceAllocation,
|
||||
test_ue->ngap_procedure_code);
|
||||
|
||||
/* Send HandoverRequestAcknowledge */
|
||||
ogs_list_for_each(&test_ue->sess_list, sess)
|
||||
sess->gnb_n3_addr = test_self()->gnb2_addr;
|
||||
|
||||
sendbuf = testngap_build_handover_request_ack(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap2, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive HandoverCommand */
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
ABTS_INT_EQUAL(tc,
|
||||
NGAP_ProcedureCode_id_HandoverPreparation,
|
||||
test_ue->ngap_procedure_code);
|
||||
|
||||
/* Send UplinkRANStatusTransfer */
|
||||
sendbuf = testngap_build_uplink_ran_status_transfer(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive DownlinkRANStatusTransfer */
|
||||
recvbuf = testgnb_ngap_read(ngap2);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
ABTS_INT_EQUAL(tc,
|
||||
NGAP_ProcedureCode_id_DownlinkRANStatusTransfer,
|
||||
test_ue->ngap_procedure_code);
|
||||
|
||||
/* Send HandoverNotify */
|
||||
test_ue->nr_cgi.cell_id = 0x40011;
|
||||
sendbuf = testngap_build_handover_notify(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap2, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive End Mark */
|
||||
recvbuf = test_gtpu_read(gtpu1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
ogs_pkbuf_free(recvbuf);
|
||||
|
||||
/* Receive UEContextReleaseCommand */
|
||||
amf_ue_ngap_id = test_ue->amf_ue_ngap_id;
|
||||
ran_ue_ngap_id = test_ue->ran_ue_ngap_id;
|
||||
|
||||
recvbuf = testgnb_ngap_read(ngap1);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(test_ue, recvbuf);
|
||||
ABTS_INT_EQUAL(tc,
|
||||
NGAP_ProcedureCode_id_UEContextRelease,
|
||||
test_ue->ngap_procedure_code);
|
||||
|
||||
/* Send UEContextReleaseComplete */
|
||||
sendbuf = testngap_build_ue_context_release_complete(test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap1, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
test_ue->amf_ue_ngap_id = amf_ue_ngap_id;
|
||||
test_ue->ran_ue_ngap_id = ran_ue_ngap_id;
|
||||
|
||||
ogs_msleep(300);
|
||||
|
||||
/********** Remove Subscriber in Database */
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue));
|
||||
|
||||
/* Two gNB disonncect from UPF */
|
||||
testgnb_gtpu_close(gtpu1);
|
||||
testgnb_gtpu_close(gtpu2);
|
||||
|
||||
/* Two gNB disonncect from AMF */
|
||||
testgnb_ngap_close(ngap1);
|
||||
testgnb_ngap_close(ngap2);
|
||||
|
||||
/* Clear Test UE Context */
|
||||
test_ue_remove(test_ue);
|
||||
}
|
||||
|
||||
abts_suite *test_5gc_n2(abts_suite *suite)
|
||||
{
|
||||
suite = ADD_SUITE(suite)
|
||||
@@ -2723,6 +3078,7 @@ abts_suite *test_5gc_n2(abts_suite *suite)
|
||||
abts_run_test(suite, direct_cancel_func, NULL);
|
||||
abts_run_test(suite, indirect_complete_func, NULL);
|
||||
abts_run_test(suite, indirect_cancel_func, NULL);
|
||||
abts_run_test(suite, partial_handover_func, NULL);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
Reference in New Issue
Block a user