[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:
Sukchan Lee 2023-01-08 13:53:48 +09:00
parent bfd5cefe53
commit 9f4a9790e3
12 changed files with 143 additions and 132 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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 {

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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)) {
/*

View File

@ -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

View File

@ -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
}

View File

@ -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);

View File

@ -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,