forked from acouzens/open5gs
[AMF] Follow-up on #1987
[AMF] Implicit Network-initiated Deregistration Two timers are introduced (both with duration of T3512 + 4 min): -MOBILE_REACHABLE -IMPLICIT_DEREGISTRATION MOBILE_REACHABLE is set when NAS connection for the UE is released. IMPLICIT_DEREGISTRATION is set when MOBILE_REACHABLE expires. On MOBILE_REACHABLE expiry Paging is ignored. On IMPLICIT_DEREGISTRATION expiry: -UE's RM_State is set to DEREGISTERED -UE is Nudm_SDM_Unsubscribed -UE is Nudm_UECM_Deregistered -PDU sessions are released -AM policies are deleted Existing flag amf_ue->network_initiated_de_reg is used.
This commit is contained in:
parent
bfd5cefe53
commit
9f4a9790e3
|
@ -370,6 +370,8 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
state = sbi_xact->state;
|
||||
|
||||
amf_ue = (amf_ue_t *)sbi_xact->sbi_object;
|
||||
ogs_assert(amf_ue);
|
||||
|
||||
|
@ -382,6 +384,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
e->amf_ue = amf_ue;
|
||||
e->h.sbi.message = &sbi_message;;
|
||||
e->h.sbi.state = state;
|
||||
|
||||
ogs_fsm_dispatch(&amf_ue->sm, e);
|
||||
} else {
|
||||
|
@ -542,6 +545,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
|||
e->amf_ue = amf_ue;
|
||||
e->sess = sess;
|
||||
e->h.sbi.message = &sbi_message;;
|
||||
e->h.sbi.state = state;
|
||||
|
||||
amf_nnssf_nsselection_handle_get(sess, &sbi_message);
|
||||
break;
|
||||
|
|
|
@ -1177,28 +1177,6 @@ void ran_ue_remove(ran_ue_t *ran_ue)
|
|||
ogs_pool_free(&ran_ue_pool, ran_ue);
|
||||
|
||||
stats_remove_ran_ue();
|
||||
if (ran_ue->amf_ue) {
|
||||
if (ran_ue->amf_ue->rm_state == RM_STATE_REGISTERED) {
|
||||
/* Start AMF_TIMER_MOBILE_REACHABLE
|
||||
* TS 24.501
|
||||
* 5.3.7 Handling of the periodic registration update timer and
|
||||
* mobile reachable timer
|
||||
* The network supervises the periodic registration update procedure
|
||||
* of the UE by means of the mobile reachable timer.
|
||||
* If the UE is not registered for emergency services,
|
||||
* the mobile reachable timer shall be longer than the value of timer
|
||||
* T3512. In this case, by default, the mobile reachable timer is
|
||||
* 4 minutes greater than the value of timer T3512.
|
||||
* The mobile reachable timer shall be reset and started with the
|
||||
* value as indicated above, when the AMF releases the NAS signalling
|
||||
* connection for the UE.
|
||||
* TODO: If the UE is registered for emergency services, the AMF shall
|
||||
* set the mobile reachable timer with a value equal to timer T3512.
|
||||
*/
|
||||
ogs_timer_start(ran_ue->amf_ue->mobile_reachable.timer,
|
||||
ogs_time_from_sec(amf_self()->time.t3512.value + 240));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ran_ue_switch_to_gnb(ran_ue_t *ran_ue, amf_gnb_t *new_gnb)
|
||||
|
@ -1434,8 +1412,6 @@ amf_ue_t *amf_ue_add(ran_ue_t *ran_ue)
|
|||
amf_ue->nas.amf.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
|
||||
amf_ue->abba_len = 2;
|
||||
|
||||
amf_ue->rm_state = RM_STATE_DEREGISTERED;
|
||||
|
||||
amf_ue_fsm_init(amf_ue);
|
||||
|
||||
ogs_list_add(&self.amf_ue_list, amf_ue);
|
||||
|
|
|
@ -403,17 +403,10 @@ struct amf_ue_s {
|
|||
long cause;
|
||||
} handover;
|
||||
|
||||
/* Network Initiated De-Registration */
|
||||
bool network_initiated_de_reg;
|
||||
|
||||
/* SubscriptionId of Subscription to Data Change Notification to UDM */
|
||||
char *data_change_subscription_id;
|
||||
|
||||
ogs_list_t sess_list;
|
||||
|
||||
#define RM_STATE_DEREGISTERED 0
|
||||
#define RM_STATE_REGISTERED 1
|
||||
uint8_t rm_state;
|
||||
};
|
||||
|
||||
typedef struct amf_sess_s {
|
||||
|
|
|
@ -740,7 +740,7 @@ int gmm_handle_authentication_response(amf_ue_t *amf_ue,
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate_confirmation, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate_confirmation, amf_ue, 0, NULL));
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
|
113
src/amf/gmm-sm.c
113
src/amf/gmm-sm.c
|
@ -53,11 +53,15 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e);
|
|||
|
||||
void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
||||
{
|
||||
int i;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
amf_sess_t *sess = NULL;
|
||||
|
||||
ogs_sbi_message_t *sbi_message = NULL;
|
||||
|
||||
int state = 0;
|
||||
|
||||
ogs_assert(e);
|
||||
|
||||
if (e->sess) {
|
||||
|
@ -71,6 +75,12 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
switch (e->h.id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
ogs_assert(amf_ue->num_of_slice <= OGS_MAX_NUM_OF_SLICE);
|
||||
for (i = 0; i < amf_ue->num_of_slice; i++) {
|
||||
amf_metrics_inst_by_slice_add(&amf_ue->nr_tai.plmn_id,
|
||||
&amf_ue->slice[i].s_nssai,
|
||||
AMF_METR_GAUGE_RM_REGISTEREDSUBNBR, -1);
|
||||
}
|
||||
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
|
||||
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
|
||||
AMF_UE_CLEAR_5GSM_MESSAGE(amf_ue);
|
||||
|
@ -123,6 +133,7 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
case OGS_EVENT_SBI_CLIENT:
|
||||
sbi_message = e->h.sbi.message;
|
||||
ogs_assert(sbi_message);
|
||||
state = e->h.sbi.state;
|
||||
|
||||
SWITCH(sbi_message->h.service.name)
|
||||
CASE(OGS_SBI_SERVICE_NAME_NAUSF_AUTH)
|
||||
|
@ -197,23 +208,24 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_free(amf_ue->data_change_subscription_id);
|
||||
amf_ue->data_change_subscription_id = NULL;
|
||||
}
|
||||
if (amf_ue->network_initiated_de_reg) {
|
||||
amf_sbi_send_release_all_sessions(
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
|
||||
if (state == AMF_NETWORK_INITIATED_DE_REGISTERED) {
|
||||
amf_sbi_send_release_all_sessions(amf_ue, state);
|
||||
if ((ogs_list_count(&amf_ue->sess_list) == 0) &&
|
||||
(PCF_AM_POLICY_ASSOCIATED(amf_ue)))
|
||||
{
|
||||
(PCF_AM_POLICY_ASSOCIATED(amf_ue))) {
|
||||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL,
|
||||
amf_npcf_am_policy_control_build_delete, amf_ue, NULL));
|
||||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL,
|
||||
NULL,
|
||||
amf_npcf_am_policy_control_build_delete,
|
||||
amf_ue, state, NULL));
|
||||
}
|
||||
} else {
|
||||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate_delete,
|
||||
amf_ue, NULL));
|
||||
amf_ue, state, NULL));
|
||||
}
|
||||
break;
|
||||
DEFAULT
|
||||
|
@ -259,7 +271,7 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_UECM, NULL,
|
||||
amf_nudm_uecm_build_registration_delete,
|
||||
amf_ue, NULL));
|
||||
amf_ue, state, NULL));
|
||||
break;
|
||||
DEFAULT
|
||||
ogs_warn("[%s] Ignore invalid HTTP method [%s]",
|
||||
|
@ -283,11 +295,10 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
break;
|
||||
|
||||
CASE(OGS_SBI_HTTP_METHOD_DELETE)
|
||||
if (!amf_ue->network_initiated_de_reg)
|
||||
if (state != AMF_NETWORK_INITIATED_DE_REGISTERED)
|
||||
ogs_assert(OGS_OK ==
|
||||
nas_5gs_send_de_registration_accept(amf_ue));
|
||||
|
||||
amf_ue->network_initiated_de_reg = false;
|
||||
PCF_AM_POLICY_CLEAR(amf_ue);
|
||||
break;
|
||||
|
||||
|
@ -317,6 +328,8 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
||||
{
|
||||
int i;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
amf_sess_t *sess = NULL;
|
||||
|
||||
|
@ -335,6 +348,12 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
switch (e->h.id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
ogs_assert(amf_ue->num_of_slice <= OGS_MAX_NUM_OF_SLICE);
|
||||
for (i = 0; i < amf_ue->num_of_slice; i++) {
|
||||
amf_metrics_inst_by_slice_add(&amf_ue->nr_tai.plmn_id,
|
||||
&amf_ue->slice[i].s_nssai,
|
||||
AMF_METR_GAUGE_RM_REGISTEREDSUBNBR, 1);
|
||||
}
|
||||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
break;
|
||||
|
@ -418,7 +437,7 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
break;
|
||||
|
||||
case AMF_TIMER_MOBILE_REACHABLE:
|
||||
ogs_info("[%s] Mobile Reachable timer expired", amf_ue->supi);
|
||||
ogs_info("[%s] Mobile Reachable Timer Expired", amf_ue->supi);
|
||||
/* Clear mobile_reachable Timers */
|
||||
CLEAR_AMF_UE_TIMER(amf_ue->mobile_reachable);
|
||||
/* Start AMF_TIMER_IMPLICIT_DEREGISTRATION
|
||||
|
@ -434,8 +453,7 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_time_from_sec(amf_self()->time.t3512.value + 240));
|
||||
break;
|
||||
case AMF_TIMER_IMPLICIT_DEREGISTRATION:
|
||||
ogs_info("[%s] Implicit de-reg timer expired, de-register UE",
|
||||
amf_ue->supi);
|
||||
ogs_info("[%s] Do Network-Initiated De-Register UE", amf_ue->supi);
|
||||
/* Clear implicit_deregistration Timers */
|
||||
CLEAR_AMF_UE_TIMER(amf_ue->implicit_deregistration);
|
||||
/* Implicitly de-register UE
|
||||
|
@ -452,9 +470,8 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
*/
|
||||
ogs_assert(true == amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
|
||||
amf_nudm_sdm_build_subscription_delete, amf_ue, NULL));
|
||||
amf_ue->network_initiated_de_reg = true;
|
||||
amf_ue->rm_state = RM_STATE_DEREGISTERED;
|
||||
amf_nudm_sdm_build_subscription_delete,
|
||||
amf_ue, AMF_NETWORK_INITIATED_DE_REGISTERED, NULL));
|
||||
OGS_FSM_TRAN(s, &gmm_state_de_registered);
|
||||
break;
|
||||
default:
|
||||
|
@ -478,7 +495,7 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
||||
{
|
||||
int rv, i, xact_count = 0;
|
||||
int rv, xact_count = 0;
|
||||
ogs_nas_5gmm_cause_t gmm_cause;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
|
@ -560,7 +577,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
|||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL,
|
||||
NULL,
|
||||
amf_npcf_am_policy_control_build_create,
|
||||
amf_ue, NULL));
|
||||
amf_ue, 0, NULL));
|
||||
OGS_FSM_TRAN(s, &gmm_state_initial_context_setup);
|
||||
break;
|
||||
}
|
||||
|
@ -583,7 +600,8 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate,
|
||||
amf_ue, 0, NULL));
|
||||
}
|
||||
|
||||
OGS_FSM_TRAN(s, &gmm_state_authentication);
|
||||
|
@ -661,7 +679,8 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate,
|
||||
amf_ue, 0, NULL));
|
||||
}
|
||||
|
||||
OGS_FSM_TRAN(s, &gmm_state_authentication);
|
||||
|
@ -678,13 +697,6 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
gmm_handle_deregistration_request(
|
||||
amf_ue, &nas_message->gmm.deregistration_request_from_ue);
|
||||
ogs_assert(amf_ue->num_of_slice <= OGS_MAX_NUM_OF_SLICE);
|
||||
for (i = 0; i < amf_ue->num_of_slice; i++) {
|
||||
amf_metrics_inst_by_slice_add(&amf_ue->nr_tai.plmn_id,
|
||||
&amf_ue->slice[i].s_nssai,
|
||||
AMF_METR_GAUGE_RM_REGISTEREDSUBNBR, -1);
|
||||
}
|
||||
amf_ue->rm_state = RM_STATE_DEREGISTERED;
|
||||
OGS_FSM_TRAN(s, &gmm_state_de_registered);
|
||||
break;
|
||||
|
||||
|
@ -700,13 +712,6 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
|||
NGAP_Cause_PR_misc, NGAP_CauseMisc_om_intervention,
|
||||
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0));
|
||||
|
||||
ogs_assert(amf_ue->num_of_slice <= OGS_MAX_NUM_OF_SLICE);
|
||||
for (i = 0; i < amf_ue->num_of_slice; i++) {
|
||||
amf_metrics_inst_by_slice_add(&amf_ue->nr_tai.plmn_id,
|
||||
&amf_ue->slice[i].s_nssai,
|
||||
AMF_METR_GAUGE_RM_REGISTEREDSUBNBR, -1);
|
||||
}
|
||||
amf_ue->rm_state = RM_STATE_DEREGISTERED;
|
||||
OGS_FSM_TRAN(s, &gmm_state_de_registered);
|
||||
break;
|
||||
|
||||
|
@ -851,7 +856,8 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate,
|
||||
amf_ue, 0, NULL));
|
||||
return;
|
||||
|
||||
case OGS_5GMM_CAUSE_SYNCH_FAILURE:
|
||||
|
@ -865,7 +871,7 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
|
|||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate,
|
||||
amf_ue, authentication_failure_parameter->auts));
|
||||
amf_ue, 0, authentication_failure_parameter->auts));
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -897,7 +903,7 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate, amf_ue, 0, NULL));
|
||||
break;
|
||||
|
||||
case OGS_NAS_5GS_5GMM_STATUS:
|
||||
|
@ -1106,7 +1112,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_UECM, NULL,
|
||||
amf_nudm_uecm_build_registration, amf_ue, NULL));
|
||||
amf_nudm_uecm_build_registration, amf_ue, 0, NULL));
|
||||
|
||||
if (amf_ue->nas.message_type == OGS_NAS_5GS_REGISTRATION_REQUEST) {
|
||||
OGS_FSM_TRAN(s, &gmm_state_initial_context_setup);
|
||||
|
@ -1142,7 +1148,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate, amf_ue, 0, NULL));
|
||||
|
||||
OGS_FSM_TRAN(s, &gmm_state_authentication);
|
||||
break;
|
||||
|
@ -1209,7 +1215,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
|
|||
|
||||
void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
||||
{
|
||||
int rv, xact_count = 0;
|
||||
int rv, state, xact_count = 0;
|
||||
ogs_nas_5gmm_cause_t gmm_cause;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
|
@ -1244,6 +1250,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
|||
case OGS_EVENT_SBI_CLIENT:
|
||||
sbi_message = e->h.sbi.message;
|
||||
ogs_assert(sbi_message);
|
||||
state = e->h.sbi.state;
|
||||
|
||||
SWITCH(sbi_message->h.service.name)
|
||||
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
|
||||
|
@ -1268,7 +1275,8 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
|||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
|
||||
amf_nudm_sdm_build_get,
|
||||
amf_ue, (char *)OGS_SBI_RESOURCE_NAME_AM_DATA));
|
||||
amf_ue, state,
|
||||
(char *)OGS_SBI_RESOURCE_NAME_AM_DATA));
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
|
@ -1303,7 +1311,8 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
rv = amf_nudm_sdm_handle_provisioned(amf_ue, sbi_message);
|
||||
rv = amf_nudm_sdm_handle_provisioned(
|
||||
amf_ue, state, sbi_message);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("[%s] amf_nudm_sdm_handle_provisioned(%s) failed",
|
||||
amf_ue->supi, sbi_message->h.resource.component[1]);
|
||||
|
@ -1388,16 +1397,6 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
|||
switch (nas_message->gmm.h.message_type) {
|
||||
case OGS_NAS_5GS_REGISTRATION_COMPLETE:
|
||||
ogs_info("[%s] Registration complete", amf_ue->supi);
|
||||
if (amf_ue->rm_state == RM_STATE_DEREGISTERED){
|
||||
int i;
|
||||
ogs_assert(amf_ue->num_of_slice <= OGS_MAX_NUM_OF_SLICE);
|
||||
for (i = 0; i < amf_ue->num_of_slice; i++) {
|
||||
amf_metrics_inst_by_slice_add(&amf_ue->nr_tai.plmn_id,
|
||||
&amf_ue->slice[i].s_nssai,
|
||||
AMF_METR_GAUGE_RM_REGISTEREDSUBNBR, 1);
|
||||
}
|
||||
}
|
||||
amf_ue->rm_state = RM_STATE_REGISTERED;
|
||||
|
||||
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
|
||||
|
||||
|
@ -1480,7 +1479,8 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate,
|
||||
amf_ue, 0, NULL));
|
||||
}
|
||||
OGS_FSM_TRAN(s, &gmm_state_authentication);
|
||||
break;
|
||||
|
@ -1646,7 +1646,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
|
|||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL,
|
||||
NULL,
|
||||
amf_npcf_am_policy_control_build_create,
|
||||
amf_ue, NULL));
|
||||
amf_ue, 0, NULL));
|
||||
OGS_FSM_TRAN(s, &gmm_state_initial_context_setup);
|
||||
break;
|
||||
}
|
||||
|
@ -1669,7 +1669,8 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate,
|
||||
amf_ue, 0, NULL));
|
||||
}
|
||||
|
||||
OGS_FSM_TRAN(s, &gmm_state_authentication);
|
||||
|
|
|
@ -499,37 +499,38 @@ cleanup:
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
static int network_deregister (
|
||||
amf_ue_t *amf_ue, OpenAPI_deregistration_reason_e dereg_reason) {
|
||||
static int do_network_initiated_de_register(
|
||||
amf_ue_t *amf_ue, OpenAPI_deregistration_reason_e dereg_reason)
|
||||
{
|
||||
if ((CM_CONNECTED(amf_ue)) &&
|
||||
(OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered)))
|
||||
{
|
||||
amf_ue->network_initiated_de_reg = true;
|
||||
(OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered))) {
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
nas_5gs_send_de_registration_request(amf_ue, dereg_reason));
|
||||
|
||||
amf_sbi_send_release_all_sessions(
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
amf_ue, AMF_NETWORK_INITIATED_DE_REGISTERED);
|
||||
|
||||
if ((ogs_list_count(&amf_ue->sess_list) == 0) &&
|
||||
(PCF_AM_POLICY_ASSOCIATED(amf_ue)))
|
||||
{
|
||||
(PCF_AM_POLICY_ASSOCIATED(amf_ue))) {
|
||||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL,
|
||||
amf_npcf_am_policy_control_build_delete, amf_ue, NULL));
|
||||
amf_npcf_am_policy_control_build_delete,
|
||||
amf_ue, AMF_NETWORK_INITIATED_DE_REGISTERED, NULL));
|
||||
}
|
||||
|
||||
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_de_registered);
|
||||
return OGS_OK;
|
||||
}
|
||||
else if (CM_IDLE(amf_ue)) {
|
||||
|
||||
} else if (CM_IDLE(amf_ue)) {
|
||||
/* TODO: need to page UE */
|
||||
/*ngap_send_paging(amf_ue);*/
|
||||
return OGS_OK;
|
||||
ogs_error("Not implemented : need to page UE");
|
||||
return OGS_ERROR;
|
||||
} else {
|
||||
return OGS_ERROR;
|
||||
ogs_fatal("Invalid State");
|
||||
ogs_assert_if_reached();
|
||||
return OGS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,8 +589,8 @@ int amf_namf_callback_handle_dereg_notify(
|
|||
* session associated with non-emergency service as described in clause 4.3.4.
|
||||
*/
|
||||
|
||||
if (network_deregister(
|
||||
amf_ue, DeregistrationData->dereg_reason) == -1) {
|
||||
if (do_network_initiated_de_register(
|
||||
amf_ue, DeregistrationData->dereg_reason) != OGS_OK) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
ogs_error("[%s] Deregistration notification for UE in wrong state",
|
||||
amf_ue->supi);
|
||||
|
@ -823,8 +824,7 @@ int amf_namf_callback_handle_sdm_data_change_notify(
|
|||
}
|
||||
|
||||
|
||||
OpenAPI_list_for_each(ModificationNotification->notify_items, node)
|
||||
{
|
||||
OpenAPI_list_for_each(ModificationNotification->notify_items, node) {
|
||||
OpenAPI_notify_item_t *item = node->data;
|
||||
|
||||
char *saveptr = NULL;
|
||||
|
@ -854,12 +854,11 @@ int amf_namf_callback_handle_sdm_data_change_notify(
|
|||
CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
|
||||
OpenAPI_lnode_t *node_ci;
|
||||
|
||||
OpenAPI_list_for_each(item->changes, node_ci)
|
||||
{
|
||||
OpenAPI_list_for_each(item->changes, node_ci) {
|
||||
OpenAPI_change_item_t *change_item = node_ci->data;
|
||||
if (update_rat_res(change_item, amf_ue->rat_restrictions)
|
||||
|| update_ambr(change_item, &amf_ue->ue_ambr,
|
||||
&ambr_changed)) {
|
||||
if (update_rat_res(change_item, amf_ue->rat_restrictions) ||
|
||||
update_ambr(change_item, &amf_ue->ue_ambr,
|
||||
&ambr_changed)) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -879,7 +878,8 @@ int amf_namf_callback_handle_sdm_data_change_notify(
|
|||
}
|
||||
|
||||
if (amf_ue_is_rat_restricted(amf_ue)) {
|
||||
if (network_deregister(amf_ue, OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED) == -1) {
|
||||
if (do_network_initiated_de_register(amf_ue,
|
||||
OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED) != OGS_OK) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
ogs_error("[%s] Deregistration notification for UE in wrong state",
|
||||
amf_ue->supi);
|
||||
|
@ -888,7 +888,7 @@ int amf_namf_callback_handle_sdm_data_change_notify(
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
|
||||
amf_nudm_sdm_build_subscription_delete, amf_ue, NULL));
|
||||
amf_nudm_sdm_build_subscription_delete, amf_ue, 0, NULL));
|
||||
} else if (ambr_changed) {
|
||||
ogs_pkbuf_t *ngapbuf;
|
||||
|
||||
|
|
|
@ -1571,6 +1571,32 @@ void ngap_handle_ue_context_release_action(ran_ue_t *ran_ue)
|
|||
* to prevent retransmission of NAS messages.
|
||||
*/
|
||||
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
|
||||
|
||||
/*
|
||||
* TS 24.501
|
||||
* 5.3.7 Handling of the periodic registration update timer and
|
||||
*
|
||||
* Start AMF_TIMER_MOBILE_REACHABLE
|
||||
* mobile reachable timer
|
||||
* The network supervises the periodic registration update procedure
|
||||
* of the UE by means of the mobile reachable timer.
|
||||
* If the UE is not registered for emergency services,
|
||||
* the mobile reachable timer shall be longer than the value of timer
|
||||
* T3512. In this case, by default, the mobile reachable timer is
|
||||
* 4 minutes greater than the value of timer T3512.
|
||||
* The mobile reachable timer shall be reset and started with the
|
||||
* value as indicated above, when the AMF releases the NAS signalling
|
||||
* connection for the UE.
|
||||
*
|
||||
* TODO: If the UE is registered for emergency services, the AMF shall
|
||||
* set the mobile reachable timer with a value equal to timer T3512.
|
||||
*/
|
||||
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered) &&
|
||||
ran_ue->ue_ctx_rel_action == NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK) {
|
||||
|
||||
ogs_timer_start(amf_ue->mobile_reachable.timer,
|
||||
ogs_time_from_sec(amf_self()->time.t3512.value + 240));
|
||||
}
|
||||
}
|
||||
|
||||
switch (ran_ue->ue_ctx_rel_action) {
|
||||
|
|
|
@ -236,7 +236,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL,
|
||||
NULL,
|
||||
amf_npcf_am_policy_control_build_create,
|
||||
amf_ue, NULL));
|
||||
amf_ue, 0, NULL));
|
||||
} else {
|
||||
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
|
||||
ogs_assert(OGS_OK ==
|
||||
|
@ -821,7 +821,8 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL,
|
||||
amf_npcf_am_policy_control_build_create, amf_ue, NULL));
|
||||
amf_npcf_am_policy_control_build_create,
|
||||
amf_ue, 0, NULL));
|
||||
} else {
|
||||
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
|
||||
ogs_assert(OGS_OK ==
|
||||
|
@ -866,7 +867,8 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
|
|||
/* Not reached here */
|
||||
ogs_assert_if_reached();
|
||||
|
||||
} else if (state == AMF_RELEASE_SM_CONTEXT_NO_STATE) {
|
||||
} else if (state == AMF_RELEASE_SM_CONTEXT_NO_STATE ||
|
||||
state == AMF_NETWORK_INITIATED_DE_REGISTERED) {
|
||||
/* NO_STATE */
|
||||
|
||||
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_authentication)) {
|
||||
|
@ -874,7 +876,8 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||
amf_nausf_auth_build_authenticate, amf_ue, NULL));
|
||||
amf_nausf_auth_build_authenticate,
|
||||
amf_ue, 0, NULL));
|
||||
|
||||
} else if (OGS_FSM_CHECK(&amf_ue->sm,
|
||||
gmm_state_de_registered)) {
|
||||
|
@ -893,7 +896,7 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
|
|||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL,
|
||||
amf_npcf_am_policy_control_build_delete,
|
||||
amf_ue, NULL));
|
||||
amf_ue, state, NULL));
|
||||
|
||||
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered)) {
|
||||
/*
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "nas-path.h"
|
||||
|
||||
int amf_nudm_sdm_handle_provisioned(
|
||||
amf_ue_t *amf_ue, ogs_sbi_message_t *recvmsg)
|
||||
amf_ue_t *amf_ue, int state, ogs_sbi_message_t *recvmsg)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -157,7 +157,7 @@ int amf_nudm_sdm_handle_provisioned(
|
|||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
|
||||
amf_nudm_sdm_build_get,
|
||||
amf_ue, (char *)OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA));
|
||||
amf_ue, state, (char *)OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA));
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA)
|
||||
|
@ -230,7 +230,8 @@ int amf_nudm_sdm_handle_provisioned(
|
|||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
|
||||
amf_nudm_sdm_build_get,
|
||||
amf_ue, (char *)OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA));
|
||||
amf_ue, state,
|
||||
(char *)OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA));
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA)
|
||||
|
@ -241,14 +242,15 @@ int amf_nudm_sdm_handle_provisioned(
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL,
|
||||
amf_npcf_am_policy_control_build_create, amf_ue, NULL));
|
||||
amf_npcf_am_policy_control_build_create,
|
||||
amf_ue, state, NULL));
|
||||
}
|
||||
else {
|
||||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
|
||||
amf_nudm_sdm_build_subscription, amf_ue,
|
||||
(char *)OGS_SBI_RESOURCE_NAME_AM_DATA));
|
||||
amf_nudm_sdm_build_subscription,
|
||||
amf_ue, state, (char *)OGS_SBI_RESOURCE_NAME_AM_DATA));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -300,7 +302,7 @@ int amf_nudm_sdm_handle_provisioned(
|
|||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL,
|
||||
amf_npcf_am_policy_control_build_create, amf_ue, NULL));
|
||||
amf_npcf_am_policy_control_build_create, amf_ue, state, NULL));
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
#include "context.h"
|
||||
|
||||
int amf_nudm_sdm_handle_provisioned(
|
||||
amf_ue_t *amf_ue, ogs_sbi_message_t *recvmsg);
|
||||
amf_ue_t *amf_ue, int state, ogs_sbi_message_t *recvmsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ bool amf_ue_sbi_discover_and_send(
|
|||
ogs_sbi_service_type_e service_type,
|
||||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
ogs_sbi_request_t *(*build)(amf_ue_t *amf_ue, void *data),
|
||||
amf_ue_t *amf_ue, void *data)
|
||||
amf_ue_t *amf_ue, int state, void *data)
|
||||
{
|
||||
ogs_sbi_xact_t *xact = NULL;
|
||||
|
||||
|
@ -109,6 +109,8 @@ bool amf_ue_sbi_discover_and_send(
|
|||
return false;
|
||||
}
|
||||
|
||||
xact->state = state;
|
||||
|
||||
if (ogs_sbi_discover_and_send(xact) != true) {
|
||||
ogs_error("amf_ue_sbi_discover_and_send() failed");
|
||||
ogs_sbi_xact_remove(xact);
|
||||
|
|
|
@ -36,13 +36,11 @@ void amf_sbi_close(void);
|
|||
|
||||
bool amf_sbi_send_request(
|
||||
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
||||
bool amf_ue_sbi_discover_and_send(
|
||||
ogs_sbi_service_type_e service_type,
|
||||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
ogs_sbi_request_t *(*build)(amf_ue_t *amf_ue, void *data),
|
||||
amf_ue_t *amf_ue, void *data);
|
||||
|
||||
#define AMF_CREATE_SM_CONTEXT_NO_STATE 0
|
||||
|
||||
#define AMF_NETWORK_INITIATED_DE_REGISTERED 1
|
||||
|
||||
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 11
|
||||
#define AMF_UPDATE_SM_CONTEXT_SETUP_FAIL 12
|
||||
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 13
|
||||
|
@ -64,6 +62,12 @@ bool amf_ue_sbi_discover_and_send(
|
|||
#define AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED 51
|
||||
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_ALL 52
|
||||
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL 53
|
||||
|
||||
bool amf_ue_sbi_discover_and_send(
|
||||
ogs_sbi_service_type_e service_type,
|
||||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
ogs_sbi_request_t *(*build)(amf_ue_t *amf_ue, void *data),
|
||||
amf_ue_t *amf_ue, int state, void *data);
|
||||
bool amf_sess_sbi_discover_and_send(
|
||||
ogs_sbi_service_type_e service_type,
|
||||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
|
|
Loading…
Reference in New Issue