From ad9e5b28cf60ef6548190b6e30bbfc4d393013f1 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sun, 12 Mar 2023 22:06:19 +0900 Subject: [PATCH] [SBI] Added Handler for Subscription PATCH (#2152) --- lib/proto/timer.c | 6 +- lib/proto/timer.h | 4 +- lib/sbi/context.c | 8 +- lib/sbi/context.h | 5 +- lib/sbi/message.h | 6 +- lib/sbi/nnrf-build.c | 77 ++++++++++++-- lib/sbi/nnrf-build.h | 4 +- lib/sbi/nnrf-handler.c | 107 +++++++++++++++---- lib/sbi/nnrf-handler.h | 5 +- lib/sbi/nnrf-path.c | 25 ++++- lib/sbi/nnrf-path.h | 4 +- lib/sbi/timer.c | 6 ++ lib/sbi/timer.h | 3 +- src/amf/amf-sm.c | 35 ++++++- src/amf/timer.c | 2 + src/ausf/ausf-sm.c | 34 ++++++- src/bsf/bsf-sm.c | 32 +++++- src/nrf/nnrf-handler.c | 226 +++++++++++++++++++++++++++++++++++++---- src/nrf/nnrf-handler.h | 2 + src/nrf/nrf-sm.c | 6 +- src/nssf/nssf-sm.c | 34 ++++++- src/pcf/pcf-sm.c | 36 ++++++- src/scp/scp-sm.c | 32 +++++- src/smf/smf-sm.c | 33 +++++- src/smf/timer.c | 2 + src/udm/udm-sm.c | 36 ++++++- src/udr/udr-sm.c | 36 ++++++- tests/af/af-sm.c | 30 +++++- 28 files changed, 741 insertions(+), 95 deletions(-) diff --git a/lib/proto/timer.c b/lib/proto/timer.c index 70e74831d..eff0d2e99 100644 --- a/lib/proto/timer.c +++ b/lib/proto/timer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -29,6 +29,8 @@ const char *OGS_TIMER_NAME_NF_INSTANCE_VALIDITY = "OGS_TIMER_NF_INSTANCE_VALIDITY"; const char *OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY = "OGS_TIMER_SUBSCRIPTION_VALIDITY"; +const char *OGS_TIMER_NAME_SUBSCRIPTION_PATCH = + "OGS_TIMER_SUBSCRIPTION_PATCH"; const char *OGS_TIMER_NAME_SBI_CLIENT_WAIT = "OGS_TIMER_SBI_CLIENT_WAIT"; @@ -45,6 +47,8 @@ const char *ogs_timer_get_name(int timer_id) return OGS_TIMER_NAME_NF_INSTANCE_VALIDITY; case OGS_TIMER_SUBSCRIPTION_VALIDITY: return OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY; + case OGS_TIMER_SUBSCRIPTION_PATCH: + return OGS_TIMER_NAME_SUBSCRIPTION_PATCH; case OGS_TIMER_SBI_CLIENT_WAIT: return OGS_TIMER_NAME_SBI_CLIENT_WAIT; case OGS_TIMER_DBI_POLL_CHANGE_STREAM: diff --git a/lib/proto/timer.h b/lib/proto/timer.h index b027fecd3..05ac4c6ce 100644 --- a/lib/proto/timer.h +++ b/lib/proto/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -33,6 +33,7 @@ extern const char *OGS_TIMER_NAME_NF_INSTANCE_HEARTBEAT_INTERVAL; extern const char *OGS_TIMER_NAME_NF_INSTANCE_NO_HEARTBEAT; extern const char *OGS_TIMER_NAME_NF_INSTANCE_VALIDITY; extern const char *OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY; +extern const char *OGS_TIMER_NAME_SUBSCRIPTION_PATCH; extern const char *OGS_TIMER_NAME_SBI_CLIENT_WAIT; /* forward declaration */ @@ -44,6 +45,7 @@ typedef enum { OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT, OGS_TIMER_NF_INSTANCE_VALIDITY, OGS_TIMER_SUBSCRIPTION_VALIDITY, + OGS_TIMER_SUBSCRIPTION_PATCH, OGS_TIMER_SBI_CLIENT_WAIT, OGS_TIMER_DBI_POLL_CHANGE_STREAM, diff --git a/lib/sbi/context.c b/lib/sbi/context.c index d54443417..3962d7c49 100644 --- a/lib/sbi/context.c +++ b/lib/sbi/context.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -1883,9 +1883,6 @@ ogs_sbi_subscription_data_t *ogs_sbi_subscription_data_add(void) ogs_assert(subscription_data); memset(subscription_data, 0, sizeof(ogs_sbi_subscription_data_t)); - subscription_data->time.validity_duration = - ogs_app()->time.subscription.validity_duration; - ogs_list_add(&ogs_sbi_self()->subscription_data_list, subscription_data); return subscription_data; @@ -1923,6 +1920,9 @@ void ogs_sbi_subscription_data_remove( if (subscription_data->t_validity) ogs_timer_delete(subscription_data->t_validity); + if (subscription_data->t_patch) + ogs_timer_delete(subscription_data->t_patch); + if (subscription_data->client) ogs_sbi_client_remove(subscription_data->client); diff --git a/lib/sbi/context.h b/lib/sbi/context.h index b6a8c4543..8d30d83f1 100644 --- a/lib/sbi/context.h +++ b/lib/sbi/context.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -246,11 +246,14 @@ typedef struct ogs_sbi_subscription_spec_s { typedef struct ogs_sbi_subscription_data_s { ogs_lnode_t lnode; +#define OGS_SBI_VALIDITY_SEC(v) \ + ogs_time_sec(v) + (ogs_time_usec(v) ? 1 : 0) struct { int validity_duration; } time; ogs_timer_t *t_validity; /* check validation */ + ogs_timer_t *t_patch; /* for sending PATCH */ char *id; /* SubscriptionId */ char *req_nf_instance_id; /* reqNfInstanceId */ diff --git a/lib/sbi/message.h b/lib/sbi/message.h index a6c6cbb13..bfd331419 100644 --- a/lib/sbi/message.h +++ b/lib/sbi/message.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -143,6 +143,10 @@ extern "C" { #define OGS_SBI_RESOURCE_NAME_PCF_BINDINGS "pcfBindings" +#define OGS_SBI_PATCH_PATH_NF_STATUS "/nfStatus" +#define OGS_SBI_PATCH_PATH_LOAD "/load" +#define OGS_SBI_PATCH_PATH_VALIDITY_TIME "/validityTime" + #define OGS_SBI_FEATURES_IS_SET(__fEATURES, __n) \ (__fEATURES & (1 << ((__n)-1))) diff --git a/lib/sbi/nnrf-build.c b/lib/sbi/nnrf-build.c index 6f37b1bba..236891abf 100644 --- a/lib/sbi/nnrf-build.c +++ b/lib/sbi/nnrf-build.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -1215,13 +1215,13 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) OpenAPI_patch_item_t StatusItem; OpenAPI_patch_item_t LoadItem; - memset(&StatusItem, 0, sizeof(StatusItem)); - memset(&LoadItem, 0, sizeof(LoadItem)); - nf_instance = ogs_sbi_self()->nf_instance; ogs_assert(nf_instance); ogs_assert(nf_instance->id); + memset(&StatusItem, 0, sizeof(StatusItem)); + memset(&LoadItem, 0, sizeof(LoadItem)); + memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_PATCH; message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM; @@ -1239,7 +1239,7 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) } StatusItem.op = OpenAPI_patch_operation_replace; - StatusItem.path = (char *)"/nfStatus"; + StatusItem.path = (char *)OGS_SBI_PATCH_PATH_NF_STATUS; StatusItem.value = OpenAPI_any_type_create_string( OpenAPI_nf_status_ToString(OpenAPI_nf_status_REGISTERED)); if (!StatusItem.value) { @@ -1250,7 +1250,7 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) OpenAPI_list_add(PatchItemList, &StatusItem); LoadItem.op = OpenAPI_patch_operation_replace; - LoadItem.path = (char *)"/load"; + LoadItem.path = (char *)OGS_SBI_PATCH_PATH_LOAD; LoadItem.value = OpenAPI_any_type_create_number(nf_instance->load); if (!LoadItem.value) { ogs_error("No load item.value"); @@ -1388,6 +1388,71 @@ end: return request; } +ogs_sbi_request_t *ogs_nnrf_nfm_build_status_update( + ogs_sbi_subscription_data_t *subscription_data) +{ + ogs_sbi_message_t message; + ogs_sbi_request_t *request = NULL; + + OpenAPI_list_t *PatchItemList = NULL; + OpenAPI_patch_item_t ValidityItem; + char *validity_time = NULL; + + ogs_assert(subscription_data); + ogs_assert(subscription_data->id); + + memset(&ValidityItem, 0, sizeof(ValidityItem)); + + memset(&message, 0, sizeof(message)); + message.h.method = (char *)OGS_SBI_HTTP_METHOD_PATCH; + message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM; + message.h.api.version = (char *)OGS_SBI_API_V1; + message.h.resource.component[0] = + (char *)OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS; + message.h.resource.component[1] = subscription_data->id; + + message.http.content_type = (char *)OGS_SBI_CONTENT_PATCH_TYPE; + + PatchItemList = OpenAPI_list_create(); + if (!PatchItemList) { + ogs_error("No PatchItemList"); + goto end; + } + + ogs_assert(subscription_data->time.validity_duration); + validity_time = ogs_sbi_localtime_string( + ogs_time_now() + + ogs_time_from_sec(subscription_data->time.validity_duration)); + ogs_assert(validity_time); + + ValidityItem.op = OpenAPI_patch_operation_replace; + ValidityItem.path = (char *)OGS_SBI_PATCH_PATH_VALIDITY_TIME; + ValidityItem.value = OpenAPI_any_type_create_string(validity_time); + + if (!ValidityItem.value) { + ogs_error("No status item.value"); + goto end; + } + + OpenAPI_list_add(PatchItemList, &ValidityItem); + + message.PatchItemList = PatchItemList; + + request = ogs_sbi_build_request(&message); + ogs_expect(request); + +end: + if (ValidityItem.value) + OpenAPI_any_type_free(ValidityItem.value); + if (validity_time) + ogs_free(validity_time); + + if (PatchItemList) + OpenAPI_list_free(PatchItemList); + + return request; +} + ogs_sbi_request_t *ogs_nnrf_nfm_build_status_unsubscribe( ogs_sbi_subscription_data_t *subscription_data) { diff --git a/lib/sbi/nnrf-build.h b/lib/sbi/nnrf-build.h index 1aa65d490..f4c65ca57 100644 --- a/lib/sbi/nnrf-build.h +++ b/lib/sbi/nnrf-build.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -37,6 +37,8 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_de_register(void); ogs_sbi_request_t *ogs_nnrf_nfm_build_status_subscribe( ogs_sbi_subscription_data_t *subscription_data); +ogs_sbi_request_t *ogs_nnrf_nfm_build_status_update( + ogs_sbi_subscription_data_t *subscription_data); ogs_sbi_request_t *ogs_nnrf_nfm_build_status_unsubscribe( ogs_sbi_subscription_data_t *subscription_data); ogs_sbi_request_t *ogs_nnrf_nfm_build_profile_retrieve(char *nf_instance_id); diff --git a/lib/sbi/nnrf-handler.c b/lib/sbi/nnrf-handler.c index 6470ac33b..6683e3c46 100644 --- a/lib/sbi/nnrf-handler.c +++ b/lib/sbi/nnrf-handler.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -458,6 +458,68 @@ static void handle_smf_info( } } +static void handle_validity_time( + ogs_sbi_subscription_data_t *subscription_data, + char *validity_time, const char *action) +{ + ogs_time_t time, validity, patch; + + ogs_assert(validity_time); + ogs_assert(subscription_data); + ogs_assert(action); + + if (ogs_sbi_time_from_string(&time, validity_time) == false) { + ogs_error("[%s] Subscription %s until %s [parser error]", + subscription_data->id, action, validity_time); + return; + } + + validity = time - ogs_time_now(); + if (validity < 0) { + ogs_error("[%s] Subscription %s until %s [validity:%d.%06d]", + subscription_data->id, action, validity_time, + (int)ogs_time_sec(validity), (int)ogs_time_usec(validity)); + return; + } + + /* + * Store subscription_data->time.validity_duration to derive NRF validity. + * It will be used in ogs_nnrf_nfm_build_status_update(). + * + * So, you should not remove the following lines. + */ + subscription_data->time.validity_duration = OGS_SBI_VALIDITY_SEC(validity); + + if (!subscription_data->t_validity) { + subscription_data->t_validity = + ogs_timer_add(ogs_app()->timer_mgr, + ogs_timer_subscription_validity, subscription_data); + ogs_assert(subscription_data->t_validity); + } + ogs_timer_start(subscription_data->t_validity, validity); + + /* + * PATCH request will be sent before VALIDITY is expired. + */ +#define PATCH_TIME_FROM_VALIDITY(x) ((x) / 2) + patch = PATCH_TIME_FROM_VALIDITY(validity); + + if (!subscription_data->t_patch) { + subscription_data->t_patch = + ogs_timer_add(ogs_app()->timer_mgr, + ogs_timer_subscription_patch, subscription_data); + ogs_assert(subscription_data->t_patch); + } + ogs_timer_start(subscription_data->t_patch, patch); + + ogs_info("[%s] Subscription %s until %s " + "[duration:%d,validity:%d.%06d,patch:%d.%06d]", + subscription_data->id, action, validity_time, + subscription_data->time.validity_duration, + (int)ogs_time_sec(validity), (int)ogs_time_usec(validity), + (int)ogs_time_sec(patch), (int)ogs_time_usec(patch)); +} + void ogs_nnrf_nfm_handle_nf_status_subscribe( ogs_sbi_subscription_data_t *subscription_data, ogs_sbi_message_t *recvmsg) @@ -488,26 +550,31 @@ void ogs_nnrf_nfm_handle_nf_status_subscribe( subscription_data->nrf_supported_features = 0; } - if (SubscriptionData->validity_time) { -#define VALIDITY_MINIMUM (10LL * OGS_USEC_PER_SEC) /* 10 seconds */ - ogs_time_t time, duration; - if (ogs_sbi_time_from_string( - &time, SubscriptionData->validity_time) == true) { - duration = time - ogs_time_now(); - if (duration < VALIDITY_MINIMUM) { - duration = VALIDITY_MINIMUM; - ogs_warn("[%s] Forced to %lld seconds", subscription_data->id, - (long long)ogs_time_sec(VALIDITY_MINIMUM)); - } - subscription_data->t_validity = ogs_timer_add(ogs_app()->timer_mgr, - ogs_timer_subscription_validity, subscription_data); - ogs_assert(subscription_data->t_validity); - ogs_timer_start(subscription_data->t_validity, duration); - } else { - ogs_error("Cannot parse validitiyTime [%s]", - SubscriptionData->validity_time); - } + /* Subscription Validity Time */ + if (SubscriptionData->validity_time) + handle_validity_time( + subscription_data, SubscriptionData->validity_time, "created"); +} + +void ogs_nnrf_nfm_handle_nf_status_update( + ogs_sbi_subscription_data_t *subscription_data, + ogs_sbi_message_t *recvmsg) +{ + OpenAPI_subscription_data_t *SubscriptionData = NULL; + + ogs_assert(recvmsg); + ogs_assert(subscription_data); + + SubscriptionData = recvmsg->SubscriptionData; + if (!SubscriptionData) { + ogs_error("No SubscriptionData"); + return; } + + /* Subscription Validity Time */ + if (SubscriptionData->validity_time) + handle_validity_time( + subscription_data, SubscriptionData->validity_time, "updated"); } bool ogs_nnrf_nfm_handle_nf_status_notify( diff --git a/lib/sbi/nnrf-handler.h b/lib/sbi/nnrf-handler.h index e6044a9cc..1b77f61b5 100644 --- a/lib/sbi/nnrf-handler.h +++ b/lib/sbi/nnrf-handler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -32,6 +32,9 @@ void ogs_nnrf_nfm_handle_nf_profile( void ogs_nnrf_nfm_handle_nf_status_subscribe( ogs_sbi_subscription_data_t *subscription_data, ogs_sbi_message_t *recvmsg); +void ogs_nnrf_nfm_handle_nf_status_update( + ogs_sbi_subscription_data_t *subscription_data, + ogs_sbi_message_t *recvmsg); bool ogs_nnrf_nfm_handle_nf_status_notify( ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); diff --git a/lib/sbi/nnrf-path.c b/lib/sbi/nnrf-path.c index 8bdfc31a5..4775d2aa2 100644 --- a/lib/sbi/nnrf-path.c +++ b/lib/sbi/nnrf-path.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 by Sukchan Lee + * Copyright (C) 2022-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -120,6 +120,29 @@ bool ogs_nnrf_nfm_send_nf_status_subscribe( return rc; } +bool ogs_nnrf_nfm_send_nf_status_update( + ogs_sbi_subscription_data_t *subscription_data) +{ + bool rc; + ogs_sbi_request_t *request = NULL; + + ogs_assert(subscription_data); + + request = ogs_nnrf_nfm_build_status_update(subscription_data); + if (!request) { + ogs_error("No Request"); + return false; + } + + rc = ogs_sbi_send_notification_request( + OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL, request, subscription_data); + ogs_expect(rc == true); + + ogs_sbi_request_free(request); + + return rc; +} + bool ogs_nnrf_nfm_send_nf_status_unsubscribe( ogs_sbi_subscription_data_t *subscription_data) { diff --git a/lib/sbi/nnrf-path.h b/lib/sbi/nnrf-path.h index 3186c6431..c0986bf20 100644 --- a/lib/sbi/nnrf-path.h +++ b/lib/sbi/nnrf-path.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 by Sukchan Lee + * Copyright (C) 2022-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -33,6 +33,8 @@ bool ogs_nnrf_nfm_send_nf_status_subscribe( OpenAPI_nf_type_e req_nf_type, char *req_nf_instance_id, OpenAPI_nf_type_e subscr_cond_nf_type, char *subscr_cond_service_name); +bool ogs_nnrf_nfm_send_nf_status_update( + ogs_sbi_subscription_data_t *subscription_data); bool ogs_nnrf_nfm_send_nf_status_unsubscribe( ogs_sbi_subscription_data_t *subscription_data); diff --git a/lib/sbi/timer.c b/lib/sbi/timer.c index 6b513a358..add9764e8 100644 --- a/lib/sbi/timer.c +++ b/lib/sbi/timer.c @@ -31,6 +31,7 @@ static void timer_send_event(int timer_id, void *data) case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT: case OGS_TIMER_NF_INSTANCE_VALIDITY: case OGS_TIMER_SUBSCRIPTION_VALIDITY: + case OGS_TIMER_SUBSCRIPTION_PATCH: case OGS_TIMER_SBI_CLIENT_WAIT: e = ogs_event_new(OGS_EVENT_SBI_TIMER); ogs_assert(e); @@ -76,6 +77,11 @@ void ogs_timer_subscription_validity(void *data) timer_send_event(OGS_TIMER_SUBSCRIPTION_VALIDITY, data); } +void ogs_timer_subscription_patch(void *data) +{ + timer_send_event(OGS_TIMER_SUBSCRIPTION_PATCH, data); +} + void ogs_timer_sbi_client_wait_expire(void *data) { timer_send_event(OGS_TIMER_SBI_CLIENT_WAIT, data); diff --git a/lib/sbi/timer.h b/lib/sbi/timer.h index c6e03814b..aa0476b76 100644 --- a/lib/sbi/timer.h +++ b/lib/sbi/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -33,6 +33,7 @@ void ogs_timer_nf_instance_heartbeat_interval(void *data); void ogs_timer_nf_instance_no_heartbeat(void *data); void ogs_timer_nf_instance_validity(void *data); void ogs_timer_subscription_validity(void *data); +void ogs_timer_subscription_patch(void *data); void ogs_timer_sbi_client_wait_expire(void *data); #ifdef __cplusplus diff --git a/src/amf/amf-sm.c b/src/amf/amf-sm.c index ca1f9c93a..5b820079d 100644 --- a/src/amf/amf-sm.c +++ b/src/amf/amf-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -298,9 +298,23 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK) { ogs_nnrf_nfm_handle_nf_status_subscribe( subscription_data, &sbi_message); + } else { + ogs_error("HTTP response error : %d", + sbi_message.res_status); + } + break; + + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK || + sbi_message.res_status == + OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &sbi_message); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, sbi_message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + sbi_message.res_status); } break; @@ -310,7 +324,9 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) ogs_sbi_subscription_data_remove(subscription_data); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, sbi_message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + sbi_message.res_status); } break; @@ -591,11 +607,22 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("Subscription validity expired [%s]", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration diff --git a/src/amf/timer.c b/src/amf/timer.c index 9e191ee97..1908511ad 100644 --- a/src/amf/timer.c +++ b/src/amf/timer.c @@ -75,6 +75,8 @@ const char *amf_timer_get_name(int timer_id) return OGS_TIMER_NAME_NF_INSTANCE_VALIDITY; case OGS_TIMER_SUBSCRIPTION_VALIDITY: return OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY; + case OGS_TIMER_SUBSCRIPTION_PATCH: + return OGS_TIMER_NAME_SUBSCRIPTION_PATCH; case OGS_TIMER_SBI_CLIENT_WAIT: return OGS_TIMER_NAME_SBI_CLIENT_WAIT; case AMF_TIMER_NG_DELAYED_SEND: diff --git a/src/ausf/ausf-sm.c b/src/ausf/ausf-sm.c index 899a09dff..ed63a0182 100644 --- a/src/ausf/ausf-sm.c +++ b/src/ausf/ausf-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -218,9 +218,22 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e) message.res_status == OGS_SBI_HTTP_STATUS_OK) { ogs_nnrf_nfm_handle_nf_status_subscribe( subscription_data, &message); + } else { + ogs_error("HTTP response error : %d", + message.res_status); + } + break; + + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -230,7 +243,9 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e) ogs_sbi_subscription_data_remove(subscription_data); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -352,11 +367,22 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("Subscription validity expired [%s]", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration diff --git a/src/bsf/bsf-sm.c b/src/bsf/bsf-sm.c index ae13cd18e..e67ad24d4 100644 --- a/src/bsf/bsf-sm.c +++ b/src/bsf/bsf-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -245,11 +245,26 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e) } break; + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); + } else { + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); + } + break; + CASE(OGS_SBI_HTTP_METHOD_DELETE) if (message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { ogs_sbi_subscription_data_remove(subscription_data); } else { - ogs_error("HTTP response error : %d", + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", message.res_status); } break; @@ -336,11 +351,22 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("Subscription validity expired [%s]", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration diff --git a/src/nrf/nnrf-handler.c b/src/nrf/nnrf-handler.c index 84fc53575..d89afca8d 100644 --- a/src/nrf/nnrf-handler.c +++ b/src/nrf/nnrf-handler.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -125,22 +125,39 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance, CASE(OGS_SBI_HTTP_METHOD_PATCH) PatchItemList = recvmsg->PatchItemList; if (!PatchItemList) { + ogs_error("No PatchItemList Array"); ogs_assert(true == ogs_sbi_server_send_error( stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - recvmsg, "No PatchItemList Array", NULL)); + recvmsg, "No PatchItemList", NULL)); return false; } OpenAPI_list_for_each(PatchItemList, node) { OpenAPI_patch_item_t *patch_item = node->data; if (!patch_item) { + ogs_error("No PatchItem"); ogs_assert(true == ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - recvmsg, "No PatchItemList", NULL)); + recvmsg, "No PatchItem", NULL)); return false; } + + if (patch_item->op != OpenAPI_patch_operation_replace) { + ogs_error("Unknown PatchItem.Operation [%s]", + OpenAPI_patch_operation_ToString(patch_item->op)); + continue; + } + + SWITCH(patch_item->path) + CASE(OGS_SBI_PATCH_PATH_NF_STATUS) + break; + CASE(OGS_SBI_PATCH_PATH_LOAD) + break; + DEFAULT + ogs_error("Unknown PatchItem.Path [%s]", patch_item->path); + END } response = ogs_sbi_build_response( @@ -198,6 +215,7 @@ bool nrf_nnrf_handle_nf_status_subscribe( subscription_data = ogs_sbi_subscription_data_add(); ogs_assert(subscription_data); + ogs_sbi_subscription_data_set_id(subscription_data, id); ogs_assert(subscription_data->id); @@ -276,19 +294,33 @@ bool nrf_nnrf_handle_nf_status_subscribe( OGS_SBI_SETUP_CLIENT(subscription_data, client); ogs_freeaddrinfo(addr); + /* + * The NRF validity is initially set in configuration. + */ + subscription_data->time.validity_duration = + ogs_app()->time.subscription.validity_duration; + if (subscription_data->time.validity_duration) { SubscriptionData->validity_time = ogs_sbi_localtime_string( ogs_time_now() + ogs_time_from_sec( subscription_data->time.validity_duration)); ogs_assert(SubscriptionData->validity_time); - subscription_data->t_validity = ogs_timer_add(ogs_app()->timer_mgr, - nrf_timer_subscription_validity, subscription_data); - ogs_assert(subscription_data->t_validity); + if (!subscription_data->t_validity) { + subscription_data->t_validity = + ogs_timer_add(ogs_app()->timer_mgr, + nrf_timer_subscription_validity, subscription_data); + ogs_assert(subscription_data->t_validity); + } ogs_timer_start(subscription_data->t_validity, ogs_time_from_sec(subscription_data->time.validity_duration)); } + ogs_info("[%s] Subscription created until %s [validity_duration:%d]", + subscription_data->id, + SubscriptionData->validity_time, + subscription_data->time.validity_duration); + recvmsg->http.location = recvmsg->h.uri; status = OGS_SBI_HTTP_STATUS_CREATED; @@ -299,30 +331,190 @@ bool nrf_nnrf_handle_nf_status_subscribe( return true; } -bool nrf_nnrf_handle_nf_status_unsubscribe( +bool nrf_nnrf_handle_nf_status_update( ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { + ogs_sbi_response_t *response = NULL; + + OpenAPI_list_t *PatchItemList = NULL; + OpenAPI_lnode_t *node; + + ogs_sbi_message_t sendmsg; + OpenAPI_subscription_data_t SubscriptionData; + char *validity_time = NULL; + ogs_sbi_subscription_data_t *subscription_data = NULL; + ogs_assert(stream); ogs_assert(recvmsg); + memset(&SubscriptionData, 0, sizeof(SubscriptionData)); + + if (!recvmsg->h.resource.component[1]) { + ogs_error("No SubscriptionId"); + ogs_assert(true == + ogs_sbi_server_send_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No SubscriptionId", NULL)); + return false; + } + subscription_data = ogs_sbi_subscription_data_find( recvmsg->h.resource.component[1]); - if (subscription_data) { - ogs_sbi_response_t *response = NULL; - ogs_sbi_subscription_data_remove(subscription_data); - - response = ogs_sbi_build_response( - recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); - ogs_assert(response); - ogs_assert(true == ogs_sbi_server_send_response(stream, response)); - } else { - ogs_error("Not found [%s]", recvmsg->h.resource.component[1]); + if (!subscription_data) { + ogs_error("[%s] Not found", recvmsg->h.resource.component[1]); ogs_assert(true == ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_NOT_FOUND, recvmsg, "Not found", recvmsg->h.resource.component[1])); + return false; } + ogs_assert(subscription_data->id); + + PatchItemList = recvmsg->PatchItemList; + if (!PatchItemList) { + ogs_error("[%s] No PatchItemList Array", subscription_data->id); + ogs_assert(true == + ogs_sbi_server_send_error( + stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No PatchItemList", subscription_data->id)); + return false; + } + + OpenAPI_list_for_each(PatchItemList, node) { + OpenAPI_patch_item_t *patch_item = node->data; + if (!patch_item) { + ogs_error("No PatchItem"); + ogs_assert(true == + ogs_sbi_server_send_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No PatchItem", NULL)); + return false; + } + + if (patch_item->op != OpenAPI_patch_operation_replace) { + ogs_error("Unknown PatchItem.Operation [%s]", + OpenAPI_patch_operation_ToString(patch_item->op)); + continue; + } + + SWITCH(patch_item->path) + CASE(OGS_SBI_PATCH_PATH_VALIDITY_TIME) + if (patch_item->value && patch_item->value->json) + validity_time = + cJSON_GetStringValue(patch_item->value->json); + break; + DEFAULT + ogs_error("Unknown PatchItem.Path [%s]", patch_item->path); + END + } + + if (validity_time) { + ogs_time_t time, validity; + + if (ogs_sbi_time_from_string(&time, validity_time) == false) { + ogs_error("[%s] Subscription updated until %s [parser error]", + subscription_data->id, validity_time); + goto end; + } + + validity = time - ogs_time_now(); + if (validity < 0) { + ogs_error("[%s] Subscription updated until %s [validity:%d.%06d]", + subscription_data->id, validity_time, + (int)ogs_time_sec(validity), (int)ogs_time_usec(validity)); + goto end; + } + + /* + * The NRF validity is updated if NF sent the PATCH Request. + */ + subscription_data->time.validity_duration = + OGS_SBI_VALIDITY_SEC(validity); + + if (!subscription_data->t_validity) { + subscription_data->t_validity = + ogs_timer_add(ogs_app()->timer_mgr, + nrf_timer_subscription_validity, subscription_data); + ogs_assert(subscription_data->t_validity); + } + ogs_timer_start(subscription_data->t_validity, + ogs_time_from_sec(subscription_data->time.validity_duration)); + + ogs_info("[%s] Subscription updated until %s " + "[duration:%d,validity:%d.%06d]", + subscription_data->id, validity_time, + subscription_data->time.validity_duration, + (int)ogs_time_sec(validity), (int)ogs_time_usec(validity)); + + /* To send SubscriptionData to the NF */ + memset(&sendmsg, 0, sizeof(sendmsg)); + sendmsg.SubscriptionData = &SubscriptionData; + + /* Mandatory */ + SubscriptionData.nf_status_notification_uri = + subscription_data->notification_uri; + + /* Validity Time */ + SubscriptionData.validity_time = ogs_sbi_localtime_string( + ogs_time_now() + ogs_time_from_sec( + subscription_data->time.validity_duration)); + ogs_assert(SubscriptionData.validity_time); + + response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK); + ogs_assert(response); + ogs_assert(true == ogs_sbi_server_send_response(stream, response)); + + ogs_free(SubscriptionData.validity_time); + + return true; + } + +end: + response = ogs_sbi_build_response( + recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); + ogs_assert(response); + ogs_assert(true == ogs_sbi_server_send_response(stream, response)); + + return true; +} + +bool nrf_nnrf_handle_nf_status_unsubscribe( + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) +{ + ogs_sbi_response_t *response = NULL; + ogs_sbi_subscription_data_t *subscription_data = NULL; + + ogs_assert(stream); + ogs_assert(recvmsg); + + if (!recvmsg->h.resource.component[1]) { + ogs_error("No SubscriptionId"); + ogs_assert(true == + ogs_sbi_server_send_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No SubscriptionId", NULL)); + return false; + } + + subscription_data = ogs_sbi_subscription_data_find( + recvmsg->h.resource.component[1]); + if (!subscription_data) { + ogs_error("[%s] Not found", recvmsg->h.resource.component[1]); + ogs_assert(true == + ogs_sbi_server_send_error(stream, + OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Not found", recvmsg->h.resource.component[1])); + return false; + } + + ogs_assert(subscription_data->id); + ogs_sbi_subscription_data_remove(subscription_data); + + response = ogs_sbi_build_response( + recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); + ogs_assert(response); + ogs_assert(true == ogs_sbi_server_send_response(stream, response)); return true; } diff --git a/src/nrf/nnrf-handler.h b/src/nrf/nnrf-handler.h index bf34eae76..9722c1ac4 100644 --- a/src/nrf/nnrf-handler.h +++ b/src/nrf/nnrf-handler.h @@ -34,6 +34,8 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance, bool nrf_nnrf_handle_nf_status_subscribe( ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); +bool nrf_nnrf_handle_nf_status_update( + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); bool nrf_nnrf_handle_nf_status_unsubscribe( ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); diff --git a/src/nrf/nrf-sm.c b/src/nrf/nrf-sm.c index 8acba792d..61e5ff27d 100644 --- a/src/nrf/nrf-sm.c +++ b/src/nrf/nrf-sm.c @@ -166,6 +166,10 @@ void nrf_state_operational(ogs_fsm_t *s, nrf_event_t *e) nrf_nnrf_handle_nf_status_subscribe(stream, &message); break; + CASE(OGS_SBI_HTTP_METHOD_PATCH) + nrf_nnrf_handle_nf_status_update(stream, &message); + break; + CASE(OGS_SBI_HTTP_METHOD_DELETE) nrf_nnrf_handle_nf_status_unsubscribe(stream, &message); break; @@ -254,7 +258,7 @@ void nrf_state_operational(ogs_fsm_t *s, nrf_event_t *e) subscription_data = e->subscription_data; ogs_assert(subscription_data); - ogs_info("[%s] Subscription validity expired", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; diff --git a/src/nssf/nssf-sm.c b/src/nssf/nssf-sm.c index 81a05aef3..71561e713 100644 --- a/src/nssf/nssf-sm.c +++ b/src/nssf/nssf-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -181,9 +181,22 @@ void nssf_state_operational(ogs_fsm_t *s, nssf_event_t *e) message.res_status == OGS_SBI_HTTP_STATUS_OK) { ogs_nnrf_nfm_handle_nf_status_subscribe( subscription_data, &message); + } else { + ogs_error("HTTP response error : %d", + message.res_status); + } + break; + + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -193,7 +206,9 @@ void nssf_state_operational(ogs_fsm_t *s, nssf_event_t *e) ogs_sbi_subscription_data_remove(subscription_data); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -252,11 +267,22 @@ void nssf_state_operational(ogs_fsm_t *s, nssf_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("Subscription validity expired [%s]", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + default: ogs_error("Unknown timer[%s:%d]", ogs_timer_get_name(e->h.timer_id), e->h.timer_id); diff --git a/src/pcf/pcf-sm.c b/src/pcf/pcf-sm.c index e4e8adcf3..74b8cab3e 100644 --- a/src/pcf/pcf-sm.c +++ b/src/pcf/pcf-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -332,9 +332,22 @@ void pcf_state_operational(ogs_fsm_t *s, pcf_event_t *e) message.res_status == OGS_SBI_HTTP_STATUS_OK) { ogs_nnrf_nfm_handle_nf_status_subscribe( subscription_data, &message); + } else { + ogs_error("HTTP response error : %d", + message.res_status); + } + break; + + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -344,7 +357,9 @@ void pcf_state_operational(ogs_fsm_t *s, pcf_event_t *e) ogs_sbi_subscription_data_remove(subscription_data); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -582,11 +597,22 @@ void pcf_state_operational(ogs_fsm_t *s, pcf_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("[%s] Subscription validity expired", - subscription_data->id); + ogs_error("[%s] Subscription validity expired", + subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration diff --git a/src/scp/scp-sm.c b/src/scp/scp-sm.c index d6c227cfb..8613dc1cc 100644 --- a/src/scp/scp-sm.c +++ b/src/scp/scp-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -177,11 +177,26 @@ void scp_state_operational(ogs_fsm_t *s, scp_event_t *e) } break; + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); + } else { + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); + } + break; + CASE(OGS_SBI_HTTP_METHOD_DELETE) if (message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { ogs_sbi_subscription_data_remove(subscription_data); } else { - ogs_error("HTTP response error : %d", + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", message.res_status); } break; @@ -238,11 +253,22 @@ void scp_state_operational(ogs_fsm_t *s, scp_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("Subscription validity expired [%s]", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index bb5d877c9..1f0401885 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -695,12 +695,28 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) } break; + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK || + sbi_message.res_status == + OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &sbi_message); + } else { + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", + sbi_message.res_status); + } + break; + CASE(OGS_SBI_HTTP_METHOD_DELETE) if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { ogs_sbi_subscription_data_remove(subscription_data); } else { - ogs_error("HTTP response error : %d", + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", sbi_message.res_status); } break; @@ -826,11 +842,22 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("Subscription validity expired [%s]", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration diff --git a/src/smf/timer.c b/src/smf/timer.c index f9a94e102..9fb991ae5 100644 --- a/src/smf/timer.c +++ b/src/smf/timer.c @@ -32,6 +32,8 @@ const char *smf_timer_get_name(int timer_id) return OGS_TIMER_NAME_NF_INSTANCE_VALIDITY; case OGS_TIMER_SUBSCRIPTION_VALIDITY: return OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY; + case OGS_TIMER_SUBSCRIPTION_PATCH: + return OGS_TIMER_NAME_SUBSCRIPTION_PATCH; case OGS_TIMER_SBI_CLIENT_WAIT: return OGS_TIMER_NAME_SBI_CLIENT_WAIT; case SMF_TIMER_PFCP_ASSOCIATION: diff --git a/src/udm/udm-sm.c b/src/udm/udm-sm.c index 424803304..d9eab8515 100644 --- a/src/udm/udm-sm.c +++ b/src/udm/udm-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019,2020 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -249,9 +249,22 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e) message.res_status == OGS_SBI_HTTP_STATUS_OK) { ogs_nnrf_nfm_handle_nf_status_subscribe( subscription_data, &message); + } else { + ogs_error("HTTP response error : %d", + message.res_status); + } + break; + + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -261,7 +274,9 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e) ogs_sbi_subscription_data_remove(subscription_data); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -393,11 +408,22 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("[%s] Subscription validity expired", - subscription_data->id); + ogs_error("[%s] Subscription validity expired", + subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration diff --git a/src/udr/udr-sm.c b/src/udr/udr-sm.c index 4efd36e0f..a41c5600c 100644 --- a/src/udr/udr-sm.c +++ b/src/udr/udr-sm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -230,9 +230,22 @@ void udr_state_operational(ogs_fsm_t *s, udr_event_t *e) message.res_status == OGS_SBI_HTTP_STATUS_OK) { ogs_nnrf_nfm_handle_nf_status_subscribe( subscription_data, &message); + } else { + ogs_error("HTTP response error : %d", + message.res_status); + } + break; + + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -242,7 +255,9 @@ void udr_state_operational(ogs_fsm_t *s, udr_event_t *e) ogs_sbi_subscription_data_remove(subscription_data); } else { ogs_error("[%s] HTTP response error [%d]", - subscription_data->id, message.res_status); + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); } break; @@ -298,11 +313,22 @@ void udr_state_operational(ogs_fsm_t *s, udr_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("[%s] Subscription validity expired", - subscription_data->id); + ogs_error("[%s] Subscription validity expired", + subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + default: ogs_error("Unknown timer[%s:%d]", ogs_timer_get_name(e->h.timer_id), e->h.timer_id); diff --git a/tests/af/af-sm.c b/tests/af/af-sm.c index 95de0941a..0c9bfadba 100644 --- a/tests/af/af-sm.c +++ b/tests/af/af-sm.c @@ -238,11 +238,26 @@ void af_state_operational(ogs_fsm_t *s, af_event_t *e) } break; + CASE(OGS_SBI_HTTP_METHOD_PATCH) + if (message.res_status == OGS_SBI_HTTP_STATUS_OK || + message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { + ogs_nnrf_nfm_handle_nf_status_update( + subscription_data, &message); + } else { + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", + message.res_status); + } + break; + CASE(OGS_SBI_HTTP_METHOD_DELETE) if (message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) { ogs_sbi_subscription_data_remove(subscription_data); } else { - ogs_error("HTTP response error : %d", + ogs_error("[%s] HTTP response error [%d]", + subscription_data->id ? + subscription_data->id : "Unknown", message.res_status); } break; @@ -421,11 +436,22 @@ void af_state_operational(ogs_fsm_t *s, af_event_t *e) subscription_data->subscr_cond.nf_type, subscription_data->subscr_cond.service_name)); - ogs_info("Subscription validity expired [%s]", + ogs_error("[%s] Subscription validity expired", subscription_data->id); ogs_sbi_subscription_data_remove(subscription_data); break; + case OGS_TIMER_SUBSCRIPTION_PATCH: + subscription_data = e->h.sbi.data; + ogs_assert(subscription_data); + + ogs_assert(true == + ogs_nnrf_nfm_send_nf_status_update(subscription_data)); + + ogs_info("[%s] Need to update Subscription", + subscription_data->id); + break; + case OGS_TIMER_SBI_CLIENT_WAIT: /* * ogs_pollset_poll() receives the time of the expiration