diff --git a/src/amf/gmm-sm.c b/src/amf/gmm-sm.c index 2dfd41128..0ed9ca095 100644 --- a/src/amf/gmm-sm.c +++ b/src/amf/gmm-sm.c @@ -275,6 +275,46 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e) if (amf_ue->confirmation_url_for_5g_aka) ogs_free(amf_ue->confirmation_url_for_5g_aka); amf_ue->confirmation_url_for_5g_aka = NULL; + + if (state == AMF_RELEASE_SM_CONTEXT_NO_STATE || + state == AMF_UE_INITIATED_DE_REGISTERED) { + + if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, + NULL, + amf_npcf_am_policy_control_build_delete, + amf_ue, state, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } else { + r = nas_5gs_send_de_registration_accept(amf_ue); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } + + } else if (state == + AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED || + state == + AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) { + + int xact_count = amf_sess_xact_count(amf_ue); + amf_sbi_send_release_all_sessions(amf_ue, state); + + if (!AMF_SESSION_RELEASE_PENDING(amf_ue) && + amf_sess_xact_count(amf_ue) == xact_count) { + + if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, + NULL, + amf_npcf_am_policy_control_build_delete, + amf_ue, state, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } + } + } break; DEFAULT ogs_error("[%s] Invalid HTTP method [%s]", @@ -404,7 +444,16 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e) */ if (state == AMF_RELEASE_SM_CONTEXT_NO_STATE || state == AMF_UE_INITIATED_DE_REGISTERED) { - if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + + if (amf_ue->confirmation_url_for_5g_aka) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, + NULL, + amf_nausf_auth_build_authenticate_delete, + amf_ue, state, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } else if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { r = amf_ue_sbi_discover_and_send( OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL, @@ -756,6 +805,46 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e) if (amf_ue->confirmation_url_for_5g_aka) ogs_free(amf_ue->confirmation_url_for_5g_aka); amf_ue->confirmation_url_for_5g_aka = NULL; + + if (state == AMF_RELEASE_SM_CONTEXT_NO_STATE || + state == AMF_UE_INITIATED_DE_REGISTERED) { + + if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, + NULL, + amf_npcf_am_policy_control_build_delete, + amf_ue, state, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } else { + r = nas_5gs_send_de_registration_accept(amf_ue); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } + + } else if (state == + AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED || + state == + AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) { + + int xact_count = amf_sess_xact_count(amf_ue); + amf_sbi_send_release_all_sessions(amf_ue, state); + + if (!AMF_SESSION_RELEASE_PENDING(amf_ue) && + amf_sess_xact_count(amf_ue) == xact_count) { + + if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, + NULL, + amf_npcf_am_policy_control_build_delete, + amf_ue, state, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } + } + } break; DEFAULT ogs_error("[%s] Invalid HTTP method [%s]", @@ -874,42 +963,57 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e) * 1. Implicit Timer Expiration * 2. UDM_SDM_Unsubscribe * 3. UDM_UECM_Deregisration - * 4. PDU session release request - * 5. PDUSessionResourceReleaseCommand + + * 4. Authentication Result Removal + * 5. PDU session release request + * 6. PDUSessionResourceReleaseCommand + * PDU session release command - * 6. PDUSessionResourceReleaseResponse - * 7. AM_Policy_Association_Termination + * 7. PDUSessionResourceReleaseResponse + * 8. AM_Policy_Association_Termination * * - AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED * 1. UDM_UECM_DeregistrationNotification * 2. Deregistration request * 3. UDM_SDM_Unsubscribe * 4. UDM_UECM_Deregisration - * 5. PDU session release request - * 6. PDUSessionResourceReleaseCommand + + * 5. Authentication Result Removal + * 6. PDU session release request + * 7. PDUSessionResourceReleaseCommand + * PDU session release command - * 7. PDUSessionResourceReleaseResponse - * 8. AM_Policy_Association_Termination - * 9. Deregistration accept - * 10. Signalling Connecion Release + * 8. PDUSessionResourceReleaseResponse + * 9. AM_Policy_Association_Termination + * 10. Deregistration accept + * 11. Signalling Connecion Release */ if (state == AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED || state == AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) { - amf_sbi_send_release_all_sessions(amf_ue, state); + if (amf_ue->confirmation_url_for_5g_aka) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, + NULL, + amf_nausf_auth_build_authenticate_delete, + amf_ue, state, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); - if (!AMF_SESSION_RELEASE_PENDING(amf_ue) && - amf_sess_xact_count(amf_ue) == xact_count) { - if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { - r = amf_ue_sbi_discover_and_send( - OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, - NULL, - amf_npcf_am_policy_control_build_delete, - amf_ue, state, NULL); - ogs_expect(r == OGS_OK); - ogs_assert(r != OGS_ERROR); + } else { + + amf_sbi_send_release_all_sessions(amf_ue, state); + + if (!AMF_SESSION_RELEASE_PENDING(amf_ue) && + amf_sess_xact_count(amf_ue) == xact_count) { + + if (PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, + NULL, + amf_npcf_am_policy_control_build_delete, + amf_ue, state, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } } } } else { diff --git a/src/ausf/ausf-sm.c b/src/ausf/ausf-sm.c index 9aab54a84..d2b7228dd 100644 --- a/src/ausf/ausf-sm.c +++ b/src/ausf/ausf-sm.c @@ -322,6 +322,9 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e) if (OGS_FSM_CHECK(&ausf_ue->sm, ausf_ue_state_exception)) { ogs_error("[%s] State machine exception", ausf_ue->suci); ausf_ue_remove(ausf_ue); + } else if (OGS_FSM_CHECK(&ausf_ue->sm, ausf_ue_state_deleted)) { + ogs_debug("[%s] AUSF-UE removed", ausf_ue->supi); + ausf_ue_remove(ausf_ue); } break; diff --git a/src/ausf/ausf-sm.h b/src/ausf/ausf-sm.h index aa1fd1bab..faa3344e3 100644 --- a/src/ausf/ausf-sm.h +++ b/src/ausf/ausf-sm.h @@ -33,6 +33,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e); void ausf_ue_state_initial(ogs_fsm_t *s, ausf_event_t *e); void ausf_ue_state_final(ogs_fsm_t *s, ausf_event_t *e); void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e); +void ausf_ue_state_deleted(ogs_fsm_t *s, ausf_event_t *e); void ausf_ue_state_exception(ogs_fsm_t *s, ausf_event_t *e); #define ausf_sm_debug(__pe) \ diff --git a/src/ausf/nudm-handler.c b/src/ausf/nudm-handler.c index 360c75d63..f1f4470db 100644 --- a/src/ausf/nudm-handler.c +++ b/src/ausf/nudm-handler.c @@ -243,7 +243,7 @@ bool ausf_nudm_ueau_handle_auth_removal_ind(ausf_ue_t *ausf_ue, ogs_assert(ausf_ue); ogs_assert(stream); - ausf_ue_remove(ausf_ue); + OGS_FSM_TRAN(&ausf_ue->sm, &ausf_ue_state_deleted); memset(&sendmsg, 0, sizeof(sendmsg)); response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); diff --git a/src/ausf/ue-sm.c b/src/ausf/ue-sm.c index 3c2b0c169..4a5c47af4 100644 --- a/src/ausf/ue-sm.c +++ b/src/ausf/ue-sm.c @@ -150,7 +150,8 @@ void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e) SWITCH(message->h.service.name) CASE(OGS_SBI_SERVICE_NAME_NUDM_UEAU) if (message->res_status != OGS_SBI_HTTP_STATUS_OK && - message->res_status != OGS_SBI_HTTP_STATUS_CREATED) { + message->res_status != OGS_SBI_HTTP_STATUS_CREATED && + message->res_status != OGS_SBI_HTTP_STATUS_NO_CONTENT) { if (message->res_status == OGS_SBI_HTTP_STATUS_NOT_FOUND) { ogs_warn("[%s] Cannot find SUPI [%d]", ausf_ue->suci, message->res_status); @@ -213,6 +214,30 @@ void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e) } } +void ausf_ue_state_deleted(ogs_fsm_t *s, ausf_event_t *e) +{ + ausf_ue_t *ausf_ue = NULL; + ogs_assert(s); + ogs_assert(e); + + ausf_sm_debug(e); + + ausf_ue = e->ausf_ue; + ogs_assert(ausf_ue); + + switch (e->h.id) { + case OGS_FSM_ENTRY_SIG: + break; + + case OGS_FSM_EXIT_SIG: + break; + + default: + ogs_error("[%s] Unknown event %s", ausf_ue->supi, ausf_event_get_name(e)); + break; + } +} + void ausf_ue_state_exception(ogs_fsm_t *s, ausf_event_t *e) { ausf_ue_t *ausf_ue = NULL;