From efd1780745a5630724cdbc69899751133ecdd4c0 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Thu, 24 Dec 2020 15:41:31 -0500 Subject: [PATCH] fix: update NRF issues (#727,#728,#729,#730) --- lib/sbi/context.c | 8 +- lib/sbi/context.h | 8 +- lib/sbi/conv.c | 44 +- lib/sbi/message.c | 3 +- lib/sbi/message.h | 3 +- lib/sbi/nnrf-build.c | 13 +- lib/sbi/openapi/meson.build | 1 + lib/sbi/openapi/model/subscription_data.c | 24 + lib/sbi/openapi/model/subscription_data.h | 3 + .../model/subscription_data_subscr_cond.c | 482 ++++++++++++++++++ .../model/subscription_data_subscr_cond.h | 66 +++ lib/sbi/path.c | 10 +- lib/sbi/path.h | 3 +- .../modified/TS29510_Nnrf_NFManagement.yaml | 42 +- src/amf/amf-sm.c | 7 +- src/amf/nf-sm.c | 8 +- src/amf/nnrf-handler.c | 120 +++-- src/amf/nnrf-handler.h | 8 +- src/ausf/ausf-sm.c | 7 +- src/ausf/nf-sm.c | 2 +- src/ausf/nnrf-handler.c | 122 +++-- src/ausf/nnrf-handler.h | 8 +- src/nrf/nnrf-build.c | 30 +- src/nrf/nnrf-handler.c | 68 +-- src/nrf/nnrf-handler.h | 14 +- src/nrf/sbi-path.c | 6 +- src/pcf/nf-sm.c | 2 +- src/pcf/nnrf-handler.c | 122 +++-- src/pcf/nnrf-handler.h | 8 +- src/pcf/pcf-sm.c | 7 +- src/smf/nf-sm.c | 8 +- src/smf/nnrf-handler.c | 120 +++-- src/smf/nnrf-handler.h | 8 +- src/smf/smf-sm.c | 7 +- src/udm/nf-sm.c | 2 +- src/udm/nnrf-handler.c | 122 +++-- src/udm/nnrf-handler.h | 8 +- src/udm/udm-sm.c | 7 +- src/udr/nf-sm.c | 3 - src/udr/nnrf-handler.c | 116 +++-- src/udr/nnrf-handler.h | 6 +- src/udr/udr-sm.c | 7 +- tests/app/5gc-init.c | 32 +- tests/app/app-init.c | 32 +- tests/unit/sbi-message-test.c | 142 ++++++ 45 files changed, 1438 insertions(+), 431 deletions(-) create mode 100644 lib/sbi/openapi/model/subscription_data_subscr_cond.c create mode 100644 lib/sbi/openapi/model/subscription_data_subscr_cond.h diff --git a/lib/sbi/context.c b/lib/sbi/context.c index 5e03908da..02fec7404 100644 --- a/lib/sbi/context.c +++ b/lib/sbi/context.c @@ -1089,8 +1089,8 @@ void ogs_sbi_subscription_remove(ogs_sbi_subscription_t *subscription) if (subscription->notification_uri) ogs_free(subscription->notification_uri); - if (subscription->nf_instance_id) - ogs_free(subscription->nf_instance_id); + if (subscription->req_nf_instance_id) + ogs_free(subscription->req_nf_instance_id); if (subscription->t_validity) ogs_timer_delete(subscription->t_validity); @@ -1109,8 +1109,8 @@ void ogs_sbi_subscription_remove_all_by_nf_instance_id(char *nf_instance_id) ogs_list_for_each_safe(&ogs_sbi_self()->subscription_list, next_subscription, subscription) { - if (subscription->nf_instance_id && - strcmp(subscription->nf_instance_id, nf_instance_id) == 0) { + if (subscription->req_nf_instance_id && + strcmp(subscription->req_nf_instance_id, nf_instance_id) == 0) { ogs_sbi_subscription_remove(subscription); } } diff --git a/lib/sbi/context.h b/lib/sbi/context.h index 9b62e45df..68e773f5a 100644 --- a/lib/sbi/context.h +++ b/lib/sbi/context.h @@ -179,11 +179,15 @@ typedef struct ogs_sbi_subscription_s { ogs_timer_t *t_validity; /* check validation */ char *id; /* SubscriptionId */ - char *nf_instance_id; /* NFInstanceId */ - OpenAPI_nf_type_e nf_type; + char *req_nf_instance_id; /* reqNfInstanceId */ + OpenAPI_nf_type_e req_nf_type; /* reqNfType */ OpenAPI_nf_status_e nf_status; char *notification_uri; + struct { + OpenAPI_nf_type_e nf_type; /* nfType */ + } subscr_cond; + void *client; /* only used in SERVER */ } ogs_sbi_subscription_t; diff --git a/lib/sbi/conv.c b/lib/sbi/conv.c index 509ff1644..819bbbf08 100644 --- a/lib/sbi/conv.c +++ b/lib/sbi/conv.c @@ -233,16 +233,38 @@ uint64_t ogs_sbi_bitrate_from_string(char *str) #define MAX_TIMESTR_LEN 128 +static int ogs_strftimezone(char *str, size_t size, int tm_gmtoff) +{ + uint8_t off_sign; + int off; + + ogs_assert(str); + ogs_assert(size); + + off_sign = '+'; + off = tm_gmtoff; + if (tm_gmtoff < 0) { + off_sign = '-'; + off = -off; + } + + return ogs_snprintf(str, size, "%c%02d:%02d", + off_sign, off / 3600, off % 3600); +} + char *ogs_sbi_localtime_string(ogs_time_t timestamp) { struct tm tm; char datetime[MAX_TIMESTR_LEN]; char timezone[MAX_TIMESTR_LEN]; + int len; ogs_localtime(ogs_time_sec(timestamp), &tm); ogs_strftime(datetime, sizeof datetime, "%Y-%m-%dT%H:%M:%S", &tm); - ogs_strftime(timezone, sizeof timezone, "%z", &tm); + + len = ogs_strftimezone(timezone, MAX_TIMESTR_LEN, tm.tm_gmtoff); + ogs_assert(len == 6); return ogs_msprintf("%s.%06lld%s", datetime, (long long)ogs_time_usec(timestamp), timezone); @@ -263,13 +285,11 @@ char *ogs_sbi_gmtime_string(ogs_time_t timestamp) char *ogs_sbi_timezone_string(int tm_gmtoff) { - struct tm tm; - char timezone[MAX_TIMESTR_LEN]; + int len; - ogs_localtime(ogs_time_now(), &tm); - tm.tm_gmtoff = tm_gmtoff; - ogs_strftime(timezone, sizeof timezone, "%z", &tm); + len = ogs_strftimezone(timezone, MAX_TIMESTR_LEN, tm_gmtoff); + ogs_assert(len == 6); return ogs_msprintf("%s", timezone); } @@ -297,8 +317,16 @@ bool ogs_sbi_time_from_string(ogs_time_t *timestamp, char *str) else if (is_seconds == false && (str[i] < '0' || str[i] > '9')) is_seconds = true; - if (is_seconds == true) seconds[j++] = str[i]; - else subsecs[k++] = str[i]; + if (is_seconds == true) { + if (str[i] == ':' && i >= 3 && + (str[i-3] == '+' || str[i-3] == '-')) { + /* skip timezone ':' character */ + } else { + seconds[j++] = str[i]; + } + } else { + subsecs[k++] = str[i]; + } i++; } diff --git a/lib/sbi/message.c b/lib/sbi/message.c index b4637c113..865426b1a 100644 --- a/lib/sbi/message.c +++ b/lib/sbi/message.c @@ -507,8 +507,7 @@ ogs_pkbuf_t *ogs_sbi_find_part_by_content_id( return NULL; } -int ogs_sbi_parse_header( - ogs_sbi_message_t *message, ogs_sbi_header_t *header) +int ogs_sbi_parse_header(ogs_sbi_message_t *message, ogs_sbi_header_t *header) { struct yuarel yuarel; char *saveptr = NULL; diff --git a/lib/sbi/message.h b/lib/sbi/message.h index c4e026077..2c6ad1463 100644 --- a/lib/sbi/message.h +++ b/lib/sbi/message.h @@ -340,8 +340,7 @@ void *ogs_sbi_header_get(ogs_hash_t *ht, const void *key); ogs_pkbuf_t *ogs_sbi_find_part_by_content_id( ogs_sbi_message_t *message, char *content_id); -int ogs_sbi_parse_header( - ogs_sbi_message_t *message, ogs_sbi_header_t *header); +int ogs_sbi_parse_header(ogs_sbi_message_t *message, ogs_sbi_header_t *header); void ogs_sbi_header_free(ogs_sbi_header_t *h); #ifdef __cplusplus diff --git a/lib/sbi/nnrf-build.c b/lib/sbi/nnrf-build.c index d4a476c26..b3506f417 100644 --- a/lib/sbi/nnrf-build.c +++ b/lib/sbi/nnrf-build.c @@ -341,9 +341,10 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_status_subscribe( ogs_sbi_server_t *server = NULL; OpenAPI_subscription_data_t *SubscriptionData = NULL; + OpenAPI_subscription_data_subscr_cond_t SubscrCond; ogs_assert(subscription); - ogs_assert(subscription->nf_type); + ogs_assert(subscription->req_nf_type); memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; @@ -367,8 +368,14 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_status_subscribe( ogs_sbi_server_uri(server, &header); ogs_assert(SubscriptionData->nf_status_notification_uri); - SubscriptionData->req_nf_type = subscription->nf_type; - SubscriptionData->req_nf_instance_id = subscription->nf_instance_id; + SubscriptionData->req_nf_type = subscription->req_nf_type; + SubscriptionData->req_nf_instance_id = subscription->req_nf_instance_id; + + memset(&SubscrCond, 0, sizeof(SubscrCond)); + if (subscription->subscr_cond.nf_type) { + SubscrCond.nf_type = subscription->subscr_cond.nf_type; + SubscriptionData->subscr_cond = &SubscrCond; + } message.SubscriptionData = SubscriptionData; diff --git a/lib/sbi/openapi/meson.build b/lib/sbi/openapi/meson.build index a6a733d20..02531d1e9 100644 --- a/lib/sbi/openapi/meson.build +++ b/lib/sbi/openapi/meson.build @@ -726,6 +726,7 @@ libsbi_openapi_sources = files(''' model/wireline_area.c model/wireline_service_area_restriction.c + model/subscription_data_subscr_cond.c '''.split()) libsbi_openapi_inc = include_directories('.') diff --git a/lib/sbi/openapi/model/subscription_data.c b/lib/sbi/openapi/model/subscription_data.c index 834386414..936671639 100644 --- a/lib/sbi/openapi/model/subscription_data.c +++ b/lib/sbi/openapi/model/subscription_data.c @@ -7,6 +7,7 @@ OpenAPI_subscription_data_t *OpenAPI_subscription_data_create( char *nf_status_notification_uri, char *req_nf_instance_id, + OpenAPI_subscription_data_subscr_cond_t *subscr_cond, char *subscription_id, char *validity_time, OpenAPI_list_t *req_notif_events, @@ -25,6 +26,7 @@ OpenAPI_subscription_data_t *OpenAPI_subscription_data_create( } subscription_data_local_var->nf_status_notification_uri = nf_status_notification_uri; subscription_data_local_var->req_nf_instance_id = req_nf_instance_id; + subscription_data_local_var->subscr_cond = subscr_cond; subscription_data_local_var->subscription_id = subscription_id; subscription_data_local_var->validity_time = validity_time; subscription_data_local_var->req_notif_events = req_notif_events; @@ -47,6 +49,7 @@ void OpenAPI_subscription_data_free(OpenAPI_subscription_data_t *subscription_da OpenAPI_lnode_t *node; ogs_free(subscription_data->nf_status_notification_uri); ogs_free(subscription_data->req_nf_instance_id); + OpenAPI_subscription_data_subscr_cond_free(subscription_data->subscr_cond); ogs_free(subscription_data->subscription_id); ogs_free(subscription_data->validity_time); OpenAPI_list_free(subscription_data->req_notif_events); @@ -91,6 +94,19 @@ cJSON *OpenAPI_subscription_data_convertToJSON(OpenAPI_subscription_data_t *subs } } + if (subscription_data->subscr_cond) { + cJSON *subscr_cond_local_JSON = OpenAPI_subscription_data_subscr_cond_convertToJSON(subscription_data->subscr_cond); + if (subscr_cond_local_JSON == NULL) { + ogs_error("OpenAPI_subscription_data_convertToJSON() failed [subscr_cond]"); + goto end; + } + cJSON_AddItemToObject(item, "subscrCond", subscr_cond_local_JSON); + if (item->child == NULL) { + ogs_error("OpenAPI_subscription_data_convertToJSON() failed [subscr_cond]"); + goto end; + } + } + if (subscription_data->subscription_id) { if (cJSON_AddStringToObject(item, "subscriptionId", subscription_data->subscription_id) == NULL) { ogs_error("OpenAPI_subscription_data_convertToJSON() failed [subscription_id]"); @@ -235,6 +251,13 @@ OpenAPI_subscription_data_t *OpenAPI_subscription_data_parseFromJSON(cJSON *subs } } + cJSON *subscr_cond = cJSON_GetObjectItemCaseSensitive(subscription_dataJSON, "subscrCond"); + + OpenAPI_subscription_data_subscr_cond_t *subscr_cond_local_nonprim = NULL; + if (subscr_cond) { + subscr_cond_local_nonprim = OpenAPI_subscription_data_subscr_cond_parseFromJSON(subscr_cond); + } + cJSON *subscription_id = cJSON_GetObjectItemCaseSensitive(subscription_dataJSON, "subscriptionId"); if (subscription_id) { @@ -367,6 +390,7 @@ OpenAPI_subscription_data_t *OpenAPI_subscription_data_parseFromJSON(cJSON *subs subscription_data_local_var = OpenAPI_subscription_data_create ( ogs_strdup(nf_status_notification_uri->valuestring), req_nf_instance_id ? ogs_strdup(req_nf_instance_id->valuestring) : NULL, + subscr_cond ? subscr_cond_local_nonprim : NULL, subscription_id ? ogs_strdup(subscription_id->valuestring) : NULL, validity_time ? ogs_strdup(validity_time->valuestring) : NULL, req_notif_events ? req_notif_eventsList : NULL, diff --git a/lib/sbi/openapi/model/subscription_data.h b/lib/sbi/openapi/model/subscription_data.h index 6b011c1b3..f70a4cdb5 100644 --- a/lib/sbi/openapi/model/subscription_data.h +++ b/lib/sbi/openapi/model/subscription_data.h @@ -17,6 +17,7 @@ #include "notification_event_type.h" #include "plmn_id.h" #include "snssai.h" +#include "subscription_data_subscr_cond.h" #ifdef __cplusplus extern "C" { @@ -26,6 +27,7 @@ typedef struct OpenAPI_subscription_data_s OpenAPI_subscription_data_t; typedef struct OpenAPI_subscription_data_s { char *nf_status_notification_uri; char *req_nf_instance_id; + struct OpenAPI_subscription_data_subscr_cond_s *subscr_cond; char *subscription_id; char *validity_time; OpenAPI_list_t *req_notif_events; @@ -41,6 +43,7 @@ typedef struct OpenAPI_subscription_data_s { OpenAPI_subscription_data_t *OpenAPI_subscription_data_create( char *nf_status_notification_uri, char *req_nf_instance_id, + OpenAPI_subscription_data_subscr_cond_t *subscr_cond, char *subscription_id, char *validity_time, OpenAPI_list_t *req_notif_events, diff --git a/lib/sbi/openapi/model/subscription_data_subscr_cond.c b/lib/sbi/openapi/model/subscription_data_subscr_cond.c new file mode 100644 index 000000000..9e05f7543 --- /dev/null +++ b/lib/sbi/openapi/model/subscription_data_subscr_cond.c @@ -0,0 +1,482 @@ + +#include +#include +#include +#include "subscription_data_subscr_cond.h" + +OpenAPI_subscription_data_subscr_cond_t *OpenAPI_subscription_data_subscr_cond_create( + char *nf_instance_id, + OpenAPI_nf_type_e nf_type, + char *service_name, + char *amf_set_id, + char *amf_region_id, + OpenAPI_list_t *guami_list, + OpenAPI_list_t *snssai_list, + OpenAPI_list_t *nsi_list, + char *nf_group_id, + char *nf_set_id, + char *nf_service_set_id, + OpenAPI_list_t *smf_serving_area, + OpenAPI_list_t *tai_list + ) +{ + OpenAPI_subscription_data_subscr_cond_t *subscription_data_subscr_cond_local_var = OpenAPI_malloc(sizeof(OpenAPI_subscription_data_subscr_cond_t)); + if (!subscription_data_subscr_cond_local_var) { + return NULL; + } + subscription_data_subscr_cond_local_var->nf_instance_id = nf_instance_id; + subscription_data_subscr_cond_local_var->nf_type = nf_type; + subscription_data_subscr_cond_local_var->service_name = service_name; + subscription_data_subscr_cond_local_var->amf_set_id = amf_set_id; + subscription_data_subscr_cond_local_var->amf_region_id = amf_region_id; + subscription_data_subscr_cond_local_var->guami_list = guami_list; + subscription_data_subscr_cond_local_var->snssai_list = snssai_list; + subscription_data_subscr_cond_local_var->nsi_list = nsi_list; + subscription_data_subscr_cond_local_var->nf_group_id = nf_group_id; + subscription_data_subscr_cond_local_var->nf_set_id = nf_set_id; + subscription_data_subscr_cond_local_var->nf_service_set_id = nf_service_set_id; + subscription_data_subscr_cond_local_var->smf_serving_area = smf_serving_area; + subscription_data_subscr_cond_local_var->tai_list = tai_list; + + return subscription_data_subscr_cond_local_var; +} + +void OpenAPI_subscription_data_subscr_cond_free(OpenAPI_subscription_data_subscr_cond_t *subscription_data_subscr_cond) +{ + if (NULL == subscription_data_subscr_cond) { + return; + } + OpenAPI_lnode_t *node; + ogs_free(subscription_data_subscr_cond->nf_instance_id); + ogs_free(subscription_data_subscr_cond->service_name); + ogs_free(subscription_data_subscr_cond->amf_set_id); + ogs_free(subscription_data_subscr_cond->amf_region_id); + OpenAPI_list_for_each(subscription_data_subscr_cond->guami_list, node) { + OpenAPI_guami_free(node->data); + } + OpenAPI_list_free(subscription_data_subscr_cond->guami_list); + OpenAPI_list_for_each(subscription_data_subscr_cond->snssai_list, node) { + OpenAPI_snssai_free(node->data); + } + OpenAPI_list_free(subscription_data_subscr_cond->snssai_list); + OpenAPI_list_for_each(subscription_data_subscr_cond->nsi_list, node) { + ogs_free(node->data); + } + OpenAPI_list_free(subscription_data_subscr_cond->nsi_list); + ogs_free(subscription_data_subscr_cond->nf_group_id); + ogs_free(subscription_data_subscr_cond->nf_set_id); + ogs_free(subscription_data_subscr_cond->nf_service_set_id); + OpenAPI_list_for_each(subscription_data_subscr_cond->smf_serving_area, node) { + ogs_free(node->data); + } + OpenAPI_list_free(subscription_data_subscr_cond->smf_serving_area); + OpenAPI_list_for_each(subscription_data_subscr_cond->tai_list, node) { + OpenAPI_tai_free(node->data); + } + OpenAPI_list_free(subscription_data_subscr_cond->tai_list); + ogs_free(subscription_data_subscr_cond); +} + +cJSON *OpenAPI_subscription_data_subscr_cond_convertToJSON(OpenAPI_subscription_data_subscr_cond_t *subscription_data_subscr_cond) +{ + cJSON *item = NULL; + + if (subscription_data_subscr_cond == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [SubscriptionData_subscrCond]"); + return NULL; + } + + item = cJSON_CreateObject(); + if (subscription_data_subscr_cond->nf_instance_id) { + if (cJSON_AddStringToObject(item, "nfInstanceId", subscription_data_subscr_cond->nf_instance_id) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [nf_instance_id]"); + goto end; + } + } + + if (subscription_data_subscr_cond->nf_type) { + if (cJSON_AddStringToObject(item, "nfType", OpenAPI_nf_type_ToString(subscription_data_subscr_cond->nf_type)) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [nf_type]"); + goto end; + } + } + + if (subscription_data_subscr_cond->service_name) { + if (cJSON_AddStringToObject(item, "serviceName", subscription_data_subscr_cond->service_name) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [service_name]"); + goto end; + } + } + + if (subscription_data_subscr_cond->amf_set_id) { + if (cJSON_AddStringToObject(item, "amfSetId", subscription_data_subscr_cond->amf_set_id) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [amf_set_id]"); + goto end; + } + } + + if (subscription_data_subscr_cond->amf_region_id) { + if (cJSON_AddStringToObject(item, "amfRegionId", subscription_data_subscr_cond->amf_region_id) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [amf_region_id]"); + goto end; + } + } + + if (subscription_data_subscr_cond->guami_list) { + cJSON *guami_listList = cJSON_AddArrayToObject(item, "guamiList"); + if (guami_listList == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [guami_list]"); + goto end; + } + + OpenAPI_lnode_t *guami_list_node; + if (subscription_data_subscr_cond->guami_list) { + OpenAPI_list_for_each(subscription_data_subscr_cond->guami_list, guami_list_node) { + cJSON *itemLocal = OpenAPI_guami_convertToJSON(guami_list_node->data); + if (itemLocal == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [guami_list]"); + goto end; + } + cJSON_AddItemToArray(guami_listList, itemLocal); + } + } + } + + if (subscription_data_subscr_cond->snssai_list) { + cJSON *snssai_listList = cJSON_AddArrayToObject(item, "snssaiList"); + if (snssai_listList == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [snssai_list]"); + goto end; + } + + OpenAPI_lnode_t *snssai_list_node; + if (subscription_data_subscr_cond->snssai_list) { + OpenAPI_list_for_each(subscription_data_subscr_cond->snssai_list, snssai_list_node) { + cJSON *itemLocal = OpenAPI_snssai_convertToJSON(snssai_list_node->data); + if (itemLocal == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [snssai_list]"); + goto end; + } + cJSON_AddItemToArray(snssai_listList, itemLocal); + } + } + } + + if (subscription_data_subscr_cond->nsi_list) { + cJSON *nsi_list = cJSON_AddArrayToObject(item, "nsiList"); + if (nsi_list == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [nsi_list]"); + goto end; + } + + OpenAPI_lnode_t *nsi_list_node; + OpenAPI_list_for_each(subscription_data_subscr_cond->nsi_list, nsi_list_node) { + if (cJSON_AddStringToObject(nsi_list, "", (char*)nsi_list_node->data) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [nsi_list]"); + goto end; + } + } + } + + if (subscription_data_subscr_cond->nf_group_id) { + if (cJSON_AddStringToObject(item, "nfGroupId", subscription_data_subscr_cond->nf_group_id) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [nf_group_id]"); + goto end; + } + } + + if (subscription_data_subscr_cond->nf_set_id) { + if (cJSON_AddStringToObject(item, "nfSetId", subscription_data_subscr_cond->nf_set_id) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [nf_set_id]"); + goto end; + } + } + + if (subscription_data_subscr_cond->nf_service_set_id) { + if (cJSON_AddStringToObject(item, "nfServiceSetId", subscription_data_subscr_cond->nf_service_set_id) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [nf_service_set_id]"); + goto end; + } + } + + if (subscription_data_subscr_cond->smf_serving_area) { + cJSON *smf_serving_area = cJSON_AddArrayToObject(item, "smfServingArea"); + if (smf_serving_area == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [smf_serving_area]"); + goto end; + } + + OpenAPI_lnode_t *smf_serving_area_node; + OpenAPI_list_for_each(subscription_data_subscr_cond->smf_serving_area, smf_serving_area_node) { + if (cJSON_AddStringToObject(smf_serving_area, "", (char*)smf_serving_area_node->data) == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [smf_serving_area]"); + goto end; + } + } + } + + if (subscription_data_subscr_cond->tai_list) { + cJSON *tai_listList = cJSON_AddArrayToObject(item, "taiList"); + if (tai_listList == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [tai_list]"); + goto end; + } + + OpenAPI_lnode_t *tai_list_node; + if (subscription_data_subscr_cond->tai_list) { + OpenAPI_list_for_each(subscription_data_subscr_cond->tai_list, tai_list_node) { + cJSON *itemLocal = OpenAPI_tai_convertToJSON(tai_list_node->data); + if (itemLocal == NULL) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed [tai_list]"); + goto end; + } + cJSON_AddItemToArray(tai_listList, itemLocal); + } + } + } + +end: + return item; +} + +OpenAPI_subscription_data_subscr_cond_t *OpenAPI_subscription_data_subscr_cond_parseFromJSON(cJSON *subscription_data_subscr_condJSON) +{ + OpenAPI_subscription_data_subscr_cond_t *subscription_data_subscr_cond_local_var = NULL; + cJSON *nf_instance_id = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "nfInstanceId"); + + if (nf_instance_id) { + if (!cJSON_IsString(nf_instance_id)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [nf_instance_id]"); + goto end; + } + } + + cJSON *nf_type = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "nfType"); + + OpenAPI_nf_type_e nf_typeVariable; + if (nf_type) { + if (!cJSON_IsString(nf_type)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [nf_type]"); + goto end; + } + nf_typeVariable = OpenAPI_nf_type_FromString(nf_type->valuestring); + } + + cJSON *service_name = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "serviceName"); + + if (service_name) { + if (!cJSON_IsString(service_name)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [service_name]"); + goto end; + } + } + + cJSON *amf_set_id = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "amfSetId"); + + if (amf_set_id) { + if (!cJSON_IsString(amf_set_id)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [amf_set_id]"); + goto end; + } + } + + cJSON *amf_region_id = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "amfRegionId"); + + if (amf_region_id) { + if (!cJSON_IsString(amf_region_id)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [amf_region_id]"); + goto end; + } + } + + cJSON *guami_list = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "guamiList"); + + OpenAPI_list_t *guami_listList; + if (guami_list) { + cJSON *guami_list_local_nonprimitive; + if (!cJSON_IsArray(guami_list)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [guami_list]"); + goto end; + } + + guami_listList = OpenAPI_list_create(); + + cJSON_ArrayForEach(guami_list_local_nonprimitive, guami_list ) { + if (!cJSON_IsObject(guami_list_local_nonprimitive)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [guami_list]"); + goto end; + } + OpenAPI_guami_t *guami_listItem = OpenAPI_guami_parseFromJSON(guami_list_local_nonprimitive); + + OpenAPI_list_add(guami_listList, guami_listItem); + } + } + + cJSON *snssai_list = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "snssaiList"); + + OpenAPI_list_t *snssai_listList; + if (snssai_list) { + cJSON *snssai_list_local_nonprimitive; + if (!cJSON_IsArray(snssai_list)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [snssai_list]"); + goto end; + } + + snssai_listList = OpenAPI_list_create(); + + cJSON_ArrayForEach(snssai_list_local_nonprimitive, snssai_list ) { + if (!cJSON_IsObject(snssai_list_local_nonprimitive)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [snssai_list]"); + goto end; + } + OpenAPI_snssai_t *snssai_listItem = OpenAPI_snssai_parseFromJSON(snssai_list_local_nonprimitive); + + OpenAPI_list_add(snssai_listList, snssai_listItem); + } + } + + cJSON *nsi_list = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "nsiList"); + + OpenAPI_list_t *nsi_listList; + if (nsi_list) { + cJSON *nsi_list_local; + if (!cJSON_IsArray(nsi_list)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [nsi_list]"); + goto end; + } + nsi_listList = OpenAPI_list_create(); + + cJSON_ArrayForEach(nsi_list_local, nsi_list) { + if (!cJSON_IsString(nsi_list_local)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [nsi_list]"); + goto end; + } + OpenAPI_list_add(nsi_listList, ogs_strdup(nsi_list_local->valuestring)); + } + } + + cJSON *nf_group_id = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "nfGroupId"); + + if (nf_group_id) { + if (!cJSON_IsString(nf_group_id)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [nf_group_id]"); + goto end; + } + } + + cJSON *nf_set_id = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "nfSetId"); + + if (nf_set_id) { + if (!cJSON_IsString(nf_set_id)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [nf_set_id]"); + goto end; + } + } + + cJSON *nf_service_set_id = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "nfServiceSetId"); + + if (nf_service_set_id) { + if (!cJSON_IsString(nf_service_set_id)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [nf_service_set_id]"); + goto end; + } + } + + cJSON *smf_serving_area = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "smfServingArea"); + + OpenAPI_list_t *smf_serving_areaList; + if (smf_serving_area) { + cJSON *smf_serving_area_local; + if (!cJSON_IsArray(smf_serving_area)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [smf_serving_area]"); + goto end; + } + smf_serving_areaList = OpenAPI_list_create(); + + cJSON_ArrayForEach(smf_serving_area_local, smf_serving_area) { + if (!cJSON_IsString(smf_serving_area_local)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [smf_serving_area]"); + goto end; + } + OpenAPI_list_add(smf_serving_areaList, ogs_strdup(smf_serving_area_local->valuestring)); + } + } + + cJSON *tai_list = cJSON_GetObjectItemCaseSensitive(subscription_data_subscr_condJSON, "taiList"); + + OpenAPI_list_t *tai_listList; + if (tai_list) { + cJSON *tai_list_local_nonprimitive; + if (!cJSON_IsArray(tai_list)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [tai_list]"); + goto end; + } + + tai_listList = OpenAPI_list_create(); + + cJSON_ArrayForEach(tai_list_local_nonprimitive, tai_list ) { + if (!cJSON_IsObject(tai_list_local_nonprimitive)) { + ogs_error("OpenAPI_subscription_data_subscr_cond_parseFromJSON() failed [tai_list]"); + goto end; + } + OpenAPI_tai_t *tai_listItem = OpenAPI_tai_parseFromJSON(tai_list_local_nonprimitive); + + OpenAPI_list_add(tai_listList, tai_listItem); + } + } + + subscription_data_subscr_cond_local_var = OpenAPI_subscription_data_subscr_cond_create ( + nf_instance_id ? ogs_strdup(nf_instance_id->valuestring) : NULL, + nf_type ? nf_typeVariable : 0, + service_name ? ogs_strdup(service_name->valuestring) : NULL, + amf_set_id ? ogs_strdup(amf_set_id->valuestring) : NULL, + amf_region_id ? ogs_strdup(amf_region_id->valuestring) : NULL, + guami_list ? guami_listList : NULL, + snssai_list ? snssai_listList : NULL, + nsi_list ? nsi_listList : NULL, + nf_group_id ? ogs_strdup(nf_group_id->valuestring) : NULL, + nf_set_id ? ogs_strdup(nf_set_id->valuestring) : NULL, + nf_service_set_id ? ogs_strdup(nf_service_set_id->valuestring) : NULL, + smf_serving_area ? smf_serving_areaList : NULL, + tai_list ? tai_listList : NULL + ); + + return subscription_data_subscr_cond_local_var; +end: + return NULL; +} + +OpenAPI_subscription_data_subscr_cond_t *OpenAPI_subscription_data_subscr_cond_copy(OpenAPI_subscription_data_subscr_cond_t *dst, OpenAPI_subscription_data_subscr_cond_t *src) +{ + cJSON *item = NULL; + char *content = NULL; + + ogs_assert(src); + item = OpenAPI_subscription_data_subscr_cond_convertToJSON(src); + if (!item) { + ogs_error("OpenAPI_subscription_data_subscr_cond_convertToJSON() failed"); + return NULL; + } + + content = cJSON_Print(item); + cJSON_Delete(item); + + if (!content) { + ogs_error("cJSON_Print() failed"); + return NULL; + } + + item = cJSON_Parse(content); + ogs_free(content); + if (!item) { + ogs_error("cJSON_Parse() failed"); + return NULL; + } + + OpenAPI_subscription_data_subscr_cond_free(dst); + dst = OpenAPI_subscription_data_subscr_cond_parseFromJSON(item); + cJSON_Delete(item); + + return dst; +} + diff --git a/lib/sbi/openapi/model/subscription_data_subscr_cond.h b/lib/sbi/openapi/model/subscription_data_subscr_cond.h new file mode 100644 index 000000000..d576b8ba5 --- /dev/null +++ b/lib/sbi/openapi/model/subscription_data_subscr_cond.h @@ -0,0 +1,66 @@ +/* + * subscription_data_subscr_cond.h + * + * + */ + +#ifndef _OpenAPI_subscription_data_subscr_cond_H_ +#define _OpenAPI_subscription_data_subscr_cond_H_ + +#include +#include "../external/cJSON.h" +#include "../include/list.h" +#include "../include/keyValuePair.h" +#include "../include/binary.h" +#include "guami.h" +#include "nf_type.h" +#include "snssai.h" +#include "tai.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OpenAPI_subscription_data_subscr_cond_s OpenAPI_subscription_data_subscr_cond_t; +typedef struct OpenAPI_subscription_data_subscr_cond_s { + char *nf_instance_id; + OpenAPI_nf_type_e nf_type; + char *service_name; + char *amf_set_id; + char *amf_region_id; + OpenAPI_list_t *guami_list; + OpenAPI_list_t *snssai_list; + OpenAPI_list_t *nsi_list; + char *nf_group_id; + char *nf_set_id; + char *nf_service_set_id; + OpenAPI_list_t *smf_serving_area; + OpenAPI_list_t *tai_list; +} OpenAPI_subscription_data_subscr_cond_t; + +OpenAPI_subscription_data_subscr_cond_t *OpenAPI_subscription_data_subscr_cond_create( + char *nf_instance_id, + OpenAPI_nf_type_e nf_type, + char *service_name, + char *amf_set_id, + char *amf_region_id, + OpenAPI_list_t *guami_list, + OpenAPI_list_t *snssai_list, + OpenAPI_list_t *nsi_list, + char *nf_group_id, + char *nf_set_id, + char *nf_service_set_id, + OpenAPI_list_t *smf_serving_area, + OpenAPI_list_t *tai_list + ); +void OpenAPI_subscription_data_subscr_cond_free(OpenAPI_subscription_data_subscr_cond_t *subscription_data_subscr_cond); +OpenAPI_subscription_data_subscr_cond_t *OpenAPI_subscription_data_subscr_cond_parseFromJSON(cJSON *subscription_data_subscr_condJSON); +cJSON *OpenAPI_subscription_data_subscr_cond_convertToJSON(OpenAPI_subscription_data_subscr_cond_t *subscription_data_subscr_cond); +OpenAPI_subscription_data_subscr_cond_t *OpenAPI_subscription_data_subscr_cond_copy(OpenAPI_subscription_data_subscr_cond_t *dst, OpenAPI_subscription_data_subscr_cond_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* _OpenAPI_subscription_data_subscr_cond_H_ */ + diff --git a/lib/sbi/path.c b/lib/sbi/path.c index bfce945cb..1c83e3527 100644 --- a/lib/sbi/path.c +++ b/lib/sbi/path.c @@ -181,7 +181,8 @@ void ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance) } void ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client, - OpenAPI_nf_type_e nf_type, char *nf_instance_id) + OpenAPI_nf_type_e req_nf_type, char *req_nf_instance_id, + OpenAPI_nf_type_e subscr_cond_nf_type) { ogs_sbi_request_t *request = NULL; ogs_sbi_subscription_t *subscription = NULL; @@ -192,9 +193,10 @@ void ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client, ogs_assert(subscription); OGS_SETUP_SBI_CLIENT(subscription, client); - subscription->nf_type = nf_type; - if (nf_instance_id) - subscription->nf_instance_id = ogs_strdup(nf_instance_id); + subscription->req_nf_type = req_nf_type; + if (req_nf_instance_id) + subscription->req_nf_instance_id = ogs_strdup(req_nf_instance_id); + subscription->subscr_cond.nf_type = subscr_cond_nf_type; request = ogs_nnrf_nfm_build_status_subscribe(subscription); ogs_assert(request); diff --git a/lib/sbi/path.h b/lib/sbi/path.h index 45ed1770c..2fe884016 100644 --- a/lib/sbi/path.h +++ b/lib/sbi/path.h @@ -36,7 +36,8 @@ void ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance); void ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance); void ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client, - OpenAPI_nf_type_e nf_type, char *nf_instance_id); + OpenAPI_nf_type_e req_nf_type, char *req_nf_instance_id, + OpenAPI_nf_type_e subscr_cond_nf_type); void ogs_nnrf_nfm_send_nf_status_unsubscribe( ogs_sbi_subscription_t *subscription); diff --git a/lib/sbi/support/modified/TS29510_Nnrf_NFManagement.yaml b/lib/sbi/support/modified/TS29510_Nnrf_NFManagement.yaml index 72b35e08c..cbeaa886b 100644 --- a/lib/sbi/support/modified/TS29510_Nnrf_NFManagement.yaml +++ b/lib/sbi/support/modified/TS29510_Nnrf_NFManagement.yaml @@ -1015,7 +1015,47 @@ components: type: string reqNfInstanceId: $ref: 'TS29571_CommonData.yaml#/components/schemas/NfInstanceId' -# subscrCond: + subscrCond: + type: object + properties: + nfInstanceId: + $ref: 'TS29571_CommonData.yaml#/components/schemas/NfInstanceId' + nfType: + $ref: '#/components/schemas/NFType' + serviceName: + $ref: '#/components/schemas/ServiceName' + amfSetId: + $ref: 'TS29571_CommonData.yaml#/components/schemas/AmfSetId' + amfRegionId: + $ref: 'TS29571_CommonData.yaml#/components/schemas/AmfRegionId' + guamiList: + type: array + items: + $ref: 'TS29571_CommonData.yaml#/components/schemas/Guami' + snssaiList: + type: array + items: + $ref: 'TS29571_CommonData.yaml#/components/schemas/Snssai' + nsiList: + type: array + items: + type: string + nfGroupId: + $ref: 'TS29571_CommonData.yaml#/components/schemas/NfGroupId' + nfSetId: + $ref: 'TS29571_CommonData.yaml#/components/schemas/NfSetId' + nfServiceSetId: + $ref: 'TS29571_CommonData.yaml#/components/schemas/NfServiceSetId' + smfServingArea: + type: array + items: + type: string + minItems: 1 + taiList: + type: array + items: + $ref: 'TS29571_CommonData.yaml#/components/schemas/Tai' + minItems: 1 # oneOf: # - $ref: '#/components/schemas/NfInstanceIdCond' # - $ref: '#/components/schemas/NfTypeCond' diff --git a/src/amf/amf-sm.c b/src/amf/amf-sm.c index 0ed0c80f6..d55786454 100644 --- a/src/amf/amf-sm.c +++ b/src/amf/amf-sm.c @@ -472,11 +472,12 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) subscription = e->sbi.data; ogs_assert(subscription); + ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, + amf_self()->nf_type, subscription->req_nf_instance_id, + subscription->subscr_cond.nf_type); + ogs_info("[%s] Subscription validity expired", subscription->id); ogs_sbi_subscription_remove(subscription); - - ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, - amf_self()->nf_type, subscription->nf_instance_id); break; case AMF_TIMER_SBI_CLIENT_WAIT: diff --git a/src/amf/nf-sm.c b/src/amf/nf-sm.c index fd229b22a..83aca2f17 100644 --- a/src/amf/nf-sm.c +++ b/src/amf/nf-sm.c @@ -210,7 +210,13 @@ void amf_nf_state_registered(ogs_fsm_t *s, amf_event_t *e) } ogs_nnrf_nfm_send_nf_status_subscribe(client, - amf_self()->nf_type, nf_instance->id); + amf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_AUSF); + ogs_nnrf_nfm_send_nf_status_subscribe(client, + amf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_UDM); + ogs_nnrf_nfm_send_nf_status_subscribe(client, + amf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_PCF); + ogs_nnrf_nfm_send_nf_status_subscribe(client, + amf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_SMF); } break; diff --git a/src/amf/nnrf-handler.c b/src/amf/nnrf-handler.c index 32fe7d1c9..c83cc0acc 100644 --- a/src/amf/nnrf-handler.c +++ b/src/amf/nnrf-handler.c @@ -23,17 +23,17 @@ #include "nnrf-handler.h" void amf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message) + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg) { OpenAPI_nf_profile_t *NFProfile = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(nf_instance); client = nf_instance->client; ogs_assert(client); - NFProfile = message->NFProfile; + NFProfile = recvmsg->NFProfile; if (!NFProfile) { ogs_error("No NFProfile"); return; @@ -44,17 +44,17 @@ void amf_nnrf_handle_nf_register( } void amf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message) + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg) { OpenAPI_subscription_data_t *SubscriptionData = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(subscription); client = subscription->client; ogs_assert(client); - SubscriptionData = message->SubscriptionData; + SubscriptionData = recvmsg->SubscriptionData; if (!SubscriptionData) { ogs_error("No SubscriptionData"); return; @@ -68,12 +68,11 @@ void amf_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { -#define VALIDITY_MARGIN (5LL * OGS_USEC_PER_SEC) /* 5 seconds */ -#define VALIDITY_MINIMUM (3600LL * OGS_USEC_PER_SEC) /* 3600 seconds */ +#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() - VALIDITY_MARGIN; + duration = time - ogs_time_now(); if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %lld seconds", subscription->id, @@ -91,79 +90,103 @@ void amf_nnrf_handle_nf_status_subscribe( } bool amf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { - ogs_sbi_response_t *response = NULL; - OpenAPI_notification_data_t *NotificationData = NULL; - OpenAPI_nf_profile_t *NFProfile = NULL; - ogs_sbi_nf_instance_t *nf_instance = NULL; + int rv; bool handled; - ogs_assert(stream); - ogs_assert(message); + ogs_sbi_response_t *response = NULL; + OpenAPI_notification_data_t *NotificationData = NULL; + ogs_sbi_nf_instance_t *nf_instance = NULL; - NotificationData = message->NotificationData; + ogs_sbi_message_t message; + ogs_sbi_header_t header; + + ogs_assert(stream); + ogs_assert(recvmsg); + + NotificationData = recvmsg->NotificationData; if (!NotificationData) { ogs_error("No NotificationData"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NotificationData", NULL); + recvmsg, "No NotificationData", NULL); return false; } - NFProfile = NotificationData->nf_profile; - if (!NFProfile) { - ogs_error("No NFProfile"); + if (!NotificationData->nf_instance_uri) { + ogs_error("No nfInstanceUri"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", NULL); + recvmsg, "No nfInstanceUri", NULL); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + memset(&header, 0, sizeof(header)); + header.uri = NotificationData->nf_instance_uri; + + rv = ogs_sbi_parse_header(&message, &header); + if (rv != OGS_OK) { + ogs_error("Cannot parse nfInstanceUri [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + if (!message.h.resource.component[1]) { + ogs_error("No nfInstanceId [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); + ogs_sbi_header_free(&header); return false; } - if (NF_INSTANCE_IS_SELF(NFProfile->nf_instance_id)) { + if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) { ogs_warn("[%s] The notification is not allowed", - NFProfile->nf_instance_id); + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN, - message, "The notification is not allowed", - NFProfile->nf_instance_id); + recvmsg, "The notification is not allowed", + message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } if (NotificationData->event == OpenAPI_notification_event_type_NF_REGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + OpenAPI_nf_profile_t *NFProfile = NULL; + + NFProfile = NotificationData->nf_profile; + if (!NFProfile) { + ogs_error("No NFProfile"); + ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No NFProfile", NULL); + ogs_sbi_header_free(&header); + return false; + } + + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (!nf_instance) { - nf_instance = ogs_sbi_nf_instance_add(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_add( + message.h.resource.component[1]); ogs_assert(nf_instance); amf_nf_fsm_init(nf_instance); ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id); + } else { OGS_FSM_TRAN(&nf_instance->sm, amf_nf_state_registered); ogs_fsm_dispatch(&nf_instance->sm, NULL); ogs_warn("[%s] (NRF-notify) NF has already been added", - NFProfile->nf_instance_id); + message.h.resource.component[1]); + } handled = ogs_sbi_nnrf_handle_nf_profile( - nf_instance, NFProfile, stream, message); + nf_instance, NFProfile, stream, recvmsg); if (!handled) { AMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } @@ -174,21 +197,24 @@ bool amf_nnrf_handle_nf_status_notify( ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Cannot find NF EndPoint", nf_instance->id); + recvmsg, "Cannot find NF EndPoint", nf_instance->id); AMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (nf_instance) { AMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); } else { - ogs_warn("[%s] (NRF-notify) Not found", NFProfile->nf_instance_id); + ogs_warn("[%s] (NRF-notify) Not found", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, - OGS_SBI_HTTP_STATUS_NOT_FOUND, - message, "Not found", message->h.resource.component[1]); + OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Not found", message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } } else { @@ -197,20 +223,22 @@ bool amf_nnrf_handle_nf_status_notify( ogs_error("Not supported event [%d:%s]", NotificationData->event, eventstr ? eventstr : "Unknown"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Not supported event", + recvmsg, "Not supported event", eventstr ? eventstr : "Unknown"); + ogs_sbi_header_free(&header); return false; } - response = ogs_sbi_build_response(message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); + ogs_sbi_header_free(&header); return true; } void amf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message) + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg) { bool handled; @@ -225,9 +253,9 @@ void amf_nnrf_handle_nf_discover( ogs_assert(xact); sbi_object = xact->sbi_object; ogs_assert(sbi_object); - ogs_assert(message); + ogs_assert(recvmsg); - SearchResult = message->SearchResult; + SearchResult = recvmsg->SearchResult; if (!SearchResult) { ogs_error("No SearchResult"); return; diff --git a/src/amf/nnrf-handler.h b/src/amf/nnrf-handler.h index 468c11f76..4bbf90e27 100644 --- a/src/amf/nnrf-handler.h +++ b/src/amf/nnrf-handler.h @@ -27,15 +27,15 @@ extern "C" { #endif void amf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message); + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg); void amf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message); + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg); bool amf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); void amf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message); + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); #ifdef __cplusplus } diff --git a/src/ausf/ausf-sm.c b/src/ausf/ausf-sm.c index 05de2bb8a..5736036fd 100644 --- a/src/ausf/ausf-sm.c +++ b/src/ausf/ausf-sm.c @@ -327,11 +327,12 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e) subscription = e->sbi.data; ogs_assert(subscription); + ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, + ausf_self()->nf_type, subscription->req_nf_instance_id, + subscription->subscr_cond.nf_type); + ogs_info("[%s] Subscription validity expired", subscription->id); ogs_sbi_subscription_remove(subscription); - - ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, - ausf_self()->nf_type, subscription->nf_instance_id); break; case AUSF_TIMER_SBI_CLIENT_WAIT: diff --git a/src/ausf/nf-sm.c b/src/ausf/nf-sm.c index 101a6bdaf..699a46436 100644 --- a/src/ausf/nf-sm.c +++ b/src/ausf/nf-sm.c @@ -210,7 +210,7 @@ void ausf_nf_state_registered(ogs_fsm_t *s, ausf_event_t *e) } ogs_nnrf_nfm_send_nf_status_subscribe(client, - ausf_self()->nf_type, nf_instance->id); + ausf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_UDM); } break; diff --git a/src/ausf/nnrf-handler.c b/src/ausf/nnrf-handler.c index 841bf09d4..7c54e5bc7 100644 --- a/src/ausf/nnrf-handler.c +++ b/src/ausf/nnrf-handler.c @@ -21,17 +21,17 @@ #include "nnrf-handler.h" void ausf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message) + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg) { OpenAPI_nf_profile_t *NFProfile = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(nf_instance); client = nf_instance->client; ogs_assert(client); - NFProfile = message->NFProfile; + NFProfile = recvmsg->NFProfile; if (!NFProfile) { ogs_error("No NFProfile"); return; @@ -42,17 +42,17 @@ void ausf_nnrf_handle_nf_register( } void ausf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message) + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg) { OpenAPI_subscription_data_t *SubscriptionData = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(subscription); client = subscription->client; ogs_assert(client); - SubscriptionData = message->SubscriptionData; + SubscriptionData = recvmsg->SubscriptionData; if (!SubscriptionData) { ogs_error("No SubscriptionData"); return; @@ -66,12 +66,11 @@ void ausf_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { -#define VALIDITY_MARGIN (5LL * OGS_USEC_PER_SEC) /* 5 seconds */ -#define VALIDITY_MINIMUM (3600LL * OGS_USEC_PER_SEC) /* 3600 seconds */ +#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() - VALIDITY_MARGIN; + duration = time - ogs_time_now(); if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %lld seconds", subscription->id, @@ -89,79 +88,103 @@ void ausf_nnrf_handle_nf_status_subscribe( } bool ausf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { - ogs_sbi_response_t *response = NULL; - OpenAPI_notification_data_t *NotificationData = NULL; - OpenAPI_nf_profile_t *NFProfile = NULL; - ogs_sbi_nf_instance_t *nf_instance = NULL; + int rv; bool handled; - ogs_assert(stream); - ogs_assert(message); + ogs_sbi_response_t *response = NULL; + OpenAPI_notification_data_t *NotificationData = NULL; + ogs_sbi_nf_instance_t *nf_instance = NULL; - NotificationData = message->NotificationData; + ogs_sbi_message_t message; + ogs_sbi_header_t header; + + ogs_assert(stream); + ogs_assert(recvmsg); + + NotificationData = recvmsg->NotificationData; if (!NotificationData) { ogs_error("No NotificationData"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NotificationData", NULL); + recvmsg, "No NotificationData", NULL); return false; } - NFProfile = NotificationData->nf_profile; - if (!NFProfile) { - ogs_error("No NFProfile"); + if (!NotificationData->nf_instance_uri) { + ogs_error("No nfInstanceUri"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", NULL); + recvmsg, "No nfInstanceUri", NULL); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + memset(&header, 0, sizeof(header)); + header.uri = NotificationData->nf_instance_uri; + + rv = ogs_sbi_parse_header(&message, &header); + if (rv != OGS_OK) { + ogs_error("Cannot parse nfInstanceUri [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + if (!message.h.resource.component[1]) { + ogs_error("No nfInstanceId [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); + ogs_sbi_header_free(&header); return false; } - if (NF_INSTANCE_IS_SELF(NFProfile->nf_instance_id)) { - ogs_warn("The notification is not allowed [%s]", - NFProfile->nf_instance_id); + if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) { + ogs_warn("[%s] The notification is not allowed", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN, - message, "The notification is not allowed", - NFProfile->nf_instance_id); + recvmsg, "The notification is not allowed", + message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } if (NotificationData->event == OpenAPI_notification_event_type_NF_REGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + OpenAPI_nf_profile_t *NFProfile = NULL; + + NFProfile = NotificationData->nf_profile; + if (!NFProfile) { + ogs_error("No NFProfile"); + ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No NFProfile", NULL); + ogs_sbi_header_free(&header); + return false; + } + + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (!nf_instance) { - nf_instance = ogs_sbi_nf_instance_add(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_add( + message.h.resource.component[1]); ogs_assert(nf_instance); ausf_nf_fsm_init(nf_instance); ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id); + } else { OGS_FSM_TRAN(&nf_instance->sm, ausf_nf_state_registered); ogs_fsm_dispatch(&nf_instance->sm, NULL); ogs_warn("[%s] (NRF-notify) NF has already been added", - NFProfile->nf_instance_id); + message.h.resource.component[1]); + } handled = ogs_sbi_nnrf_handle_nf_profile( - nf_instance, NFProfile, stream, message); + nf_instance, NFProfile, stream, recvmsg); if (!handled) { AUSF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } @@ -172,21 +195,24 @@ bool ausf_nnrf_handle_nf_status_notify( ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Cannot find NF EndPoint", nf_instance->id); + recvmsg, "Cannot find NF EndPoint", nf_instance->id); AUSF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (nf_instance) { AUSF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); } else { - ogs_warn("[%s] (NRF-notify) Not found", NFProfile->nf_instance_id); + ogs_warn("[%s] (NRF-notify) Not found", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, - OGS_SBI_HTTP_STATUS_NOT_FOUND, - message, "Not found", message->h.resource.component[1]); + OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Not found", message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } } else { @@ -195,20 +221,22 @@ bool ausf_nnrf_handle_nf_status_notify( ogs_error("Not supported event [%d:%s]", NotificationData->event, eventstr ? eventstr : "Unknown"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Not supported event", + recvmsg, "Not supported event", eventstr ? eventstr : "Unknown"); + ogs_sbi_header_free(&header); return false; } - response = ogs_sbi_build_response(message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); + ogs_sbi_header_free(&header); return true; } void ausf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message) + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg) { ogs_sbi_object_t *sbi_object = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL; @@ -223,9 +251,9 @@ void ausf_nnrf_handle_nf_discover( ogs_assert(sbi_object); stream = xact->assoc_stream; ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - SearchResult = message->SearchResult; + SearchResult = recvmsg->SearchResult; if (!SearchResult) { ogs_error("No SearchResult"); return; diff --git a/src/ausf/nnrf-handler.h b/src/ausf/nnrf-handler.h index ce03e8f1f..9ef650128 100644 --- a/src/ausf/nnrf-handler.h +++ b/src/ausf/nnrf-handler.h @@ -27,15 +27,15 @@ extern "C" { #endif void ausf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message); + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg); void ausf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message); + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg); bool ausf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); void ausf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message); + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); #ifdef __cplusplus } diff --git a/src/nrf/nnrf-build.c b/src/nrf/nnrf-build.c index 957c3249b..49bc5d0f8 100644 --- a/src/nrf/nnrf-build.c +++ b/src/nrf/nnrf-build.c @@ -27,6 +27,9 @@ ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify( ogs_sbi_message_t message; ogs_sbi_request_t *request = NULL; + ogs_sbi_header_t header; + ogs_sbi_server_t *server = NULL; + OpenAPI_notification_data_t *NotificationData = NULL; OpenAPI_nf_profile_t *NFProfile = NULL; @@ -35,8 +38,6 @@ ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify( ogs_assert(event); ogs_assert(nf_instance); - /* TODO : filter NFType */ - memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; message.h.uri = subscription->notification_uri; @@ -47,20 +48,35 @@ ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify( ogs_assert(NotificationData); NotificationData->event = event; - NotificationData->nf_instance_uri = message.h.uri; - NFProfile = ogs_nnrf_nfm_build_nf_profile(nf_instance); - ogs_assert(NFProfile); + server = ogs_list_first(&ogs_sbi_self()->server_list); + ogs_assert(server); - NotificationData->nf_profile = NFProfile; + memset(&header, 0, sizeof(header)); + header.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM; + header.api.version = (char *)OGS_SBI_API_V1; + header.resource.component[0] = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM; + header.resource.component[1] = nf_instance->id; + + NotificationData->nf_instance_uri = ogs_sbi_server_uri(server, &header); + ogs_assert(NotificationData->nf_instance_uri); + + if (event != OpenAPI_notification_event_type_NF_DEREGISTERED) { + NFProfile = ogs_nnrf_nfm_build_nf_profile(nf_instance); + ogs_assert(NFProfile); + + NotificationData->nf_profile = NFProfile; + } message.NotificationData = NotificationData; request = ogs_sbi_build_request(&message); ogs_assert(request); - ogs_sbi_nnrf_free_nf_profile(NFProfile); + if (NotificationData->nf_profile) + ogs_sbi_nnrf_free_nf_profile(NotificationData->nf_profile); + ogs_free(NotificationData->nf_instance_uri); ogs_free(NotificationData); return request; diff --git a/src/nrf/nnrf-handler.c b/src/nrf/nnrf-handler.c index 01005d5af..379c3201f 100644 --- a/src/nrf/nnrf-handler.c +++ b/src/nrf/nnrf-handler.c @@ -20,7 +20,7 @@ #include "nnrf-handler.h" bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance, - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { int status; bool handled; @@ -30,30 +30,30 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance, ogs_assert(nf_instance); ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - NFProfile = message->NFProfile; + NFProfile = recvmsg->NFProfile; if (!NFProfile) { ogs_error("No NFProfile"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", NULL); + recvmsg, "No NFProfile", NULL); return false; } /* ogs_sbi_nnrf_handle_nf_profile() sends error response */ handled = ogs_sbi_nnrf_handle_nf_profile( - nf_instance, NFProfile, stream, message); + nf_instance, NFProfile, stream, recvmsg); if (!handled) return false; if (OGS_FSM_CHECK(&nf_instance->sm, nrf_nf_state_will_register)) { - message->http.location = message->h.uri; + recvmsg->http.location = recvmsg->h.uri; status = OGS_SBI_HTTP_STATUS_CREATED; } else if (OGS_FSM_CHECK(&nf_instance->sm, nrf_nf_state_registered)) { status = OGS_SBI_HTTP_STATUS_OK; } else ogs_assert_if_reached(); - response = ogs_sbi_build_response(message, status); + response = ogs_sbi_build_response(recvmsg, status); ogs_assert(response); ogs_sbi_server_send_response(stream, response); @@ -61,7 +61,7 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance, } bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance, - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { ogs_sbi_response_t *response = NULL; OpenAPI_list_t *PatchItemList = NULL; @@ -69,18 +69,18 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance, ogs_assert(nf_instance); ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - SWITCH(message->h.method) + SWITCH(recvmsg->h.method) CASE(OGS_SBI_HTTP_METHOD_PUT) return nrf_nnrf_handle_nf_register( - nf_instance, stream, message); + nf_instance, stream, recvmsg); CASE(OGS_SBI_HTTP_METHOD_PATCH) - PatchItemList = message->PatchItemList; + PatchItemList = recvmsg->PatchItemList; if (!PatchItemList) { ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No PatchItemList Array", NULL); + recvmsg, "No PatchItemList Array", NULL); return false; } @@ -89,20 +89,20 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance, if (!patch_item) { ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No PatchItemList", NULL); + recvmsg, "No PatchItemList", NULL); return false; } } response = ogs_sbi_build_response( - message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); break; DEFAULT ogs_error("[%s] Invalid HTTP method [%s]", - nf_instance->id, message->h.method); + nf_instance->id, recvmsg->h.method); ogs_assert_if_reached(); END @@ -110,11 +110,12 @@ 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 *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { int status; ogs_sbi_response_t *response = NULL; OpenAPI_subscription_data_t *SubscriptionData = NULL; + OpenAPI_subscription_data_subscr_cond_t *SubscrCond = NULL; ogs_sbi_subscription_t *subscription = NULL; ogs_sbi_client_t *client = NULL; ogs_sockaddr_t *addr = NULL; @@ -123,18 +124,18 @@ bool nrf_nnrf_handle_nf_status_subscribe( char id[OGS_UUID_FORMATTED_LENGTH + 1]; ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - SubscriptionData = message->SubscriptionData; + SubscriptionData = recvmsg->SubscriptionData; if (!SubscriptionData) { ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No SubscriptionData", NULL); + recvmsg, "No SubscriptionData", NULL); return false; } if (!SubscriptionData->nf_status_notification_uri) { ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No SubscriptionData", "NFStatusNotificationURL"); + recvmsg, "No SubscriptionData", "NFStatusNotificationURL"); return false; } @@ -147,7 +148,7 @@ bool nrf_nnrf_handle_nf_status_subscribe( ogs_assert(subscription->id); if (SubscriptionData->req_nf_instance_id) - subscription->nf_instance_id = + subscription->req_nf_instance_id = ogs_strdup(SubscriptionData->req_nf_instance_id); if (SubscriptionData->subscription_id) { @@ -157,6 +158,11 @@ bool nrf_nnrf_handle_nf_status_subscribe( } SubscriptionData->subscription_id = ogs_strdup(subscription->id); + SubscrCond = SubscriptionData->subscr_cond; + if (SubscrCond) { + subscription->subscr_cond.nf_type = SubscrCond->nf_type; + } + subscription->notification_uri = ogs_strdup(SubscriptionData->nf_status_notification_uri); ogs_assert(subscription->notification_uri); @@ -164,7 +170,7 @@ bool nrf_nnrf_handle_nf_status_subscribe( addr = ogs_sbi_getaddr_from_uri(subscription->notification_uri); if (!addr) { ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Invalid URI", subscription->notification_uri); + recvmsg, "Invalid URI", subscription->notification_uri); ogs_sbi_subscription_remove(subscription); return false; } @@ -190,10 +196,10 @@ bool nrf_nnrf_handle_nf_status_subscribe( ogs_time_from_sec(subscription->time.validity_duration)); } - message->http.location = message->h.uri; + recvmsg->http.location = recvmsg->h.uri; status = OGS_SBI_HTTP_STATUS_CREATED; - response = ogs_sbi_build_response(message, status); + response = ogs_sbi_build_response(recvmsg, status); ogs_assert(response); ogs_sbi_server_send_response(stream, response); @@ -201,26 +207,26 @@ bool nrf_nnrf_handle_nf_status_subscribe( } bool nrf_nnrf_handle_nf_status_unsubscribe( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { ogs_sbi_subscription_t *subscription = NULL; ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - subscription = ogs_sbi_subscription_find(message->h.resource.component[1]); + subscription = ogs_sbi_subscription_find(recvmsg->h.resource.component[1]); if (subscription) { ogs_sbi_response_t *response = NULL; ogs_sbi_subscription_remove(subscription); response = ogs_sbi_build_response( - message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); } else { - ogs_error("Not found [%s]", message->h.resource.component[1]); + ogs_error("Not found [%s]", recvmsg->h.resource.component[1]); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_NOT_FOUND, - message, "Not found", message->h.resource.component[1]); + recvmsg, "Not found", recvmsg->h.resource.component[1]); } return true; diff --git a/src/nrf/nnrf-handler.h b/src/nrf/nnrf-handler.h index 24094ae5b..bf34eae76 100644 --- a/src/nrf/nnrf-handler.h +++ b/src/nrf/nnrf-handler.h @@ -28,22 +28,22 @@ extern "C" { #endif bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance, - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance, - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); bool nrf_nnrf_handle_nf_status_subscribe( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + 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 *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); bool nrf_nnrf_handle_nf_list_retrieval( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); bool nrf_nnrf_handle_nf_profile_retrieval( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); bool nrf_nnrf_handle_nf_discover( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); #ifdef __cplusplus } diff --git a/src/nrf/sbi-path.c b/src/nrf/sbi-path.c index e47e2a1b6..c3c3f7087 100644 --- a/src/nrf/sbi-path.c +++ b/src/nrf/sbi-path.c @@ -106,7 +106,11 @@ void nrf_nnrf_nfm_send_nf_status_notify_all( ogs_list_for_each(&ogs_sbi_self()->subscription_list, subscription) { - if (strcmp(subscription->nf_instance_id, nf_instance->id) == 0) + if (strcmp(subscription->req_nf_instance_id, nf_instance->id) == 0) + continue; + + if (subscription->subscr_cond.nf_type && + subscription->subscr_cond.nf_type != nf_instance->nf_type) continue; nrf_nnrf_nfm_send_nf_status_notify(subscription, event, nf_instance); diff --git a/src/pcf/nf-sm.c b/src/pcf/nf-sm.c index d64e8ef3c..196ce393f 100644 --- a/src/pcf/nf-sm.c +++ b/src/pcf/nf-sm.c @@ -210,7 +210,7 @@ void pcf_nf_state_registered(ogs_fsm_t *s, pcf_event_t *e) } ogs_nnrf_nfm_send_nf_status_subscribe(client, - pcf_self()->nf_type, nf_instance->id); + pcf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_UDR); } break; diff --git a/src/pcf/nnrf-handler.c b/src/pcf/nnrf-handler.c index 544669c48..b0827c09d 100644 --- a/src/pcf/nnrf-handler.c +++ b/src/pcf/nnrf-handler.c @@ -21,17 +21,17 @@ #include "nnrf-handler.h" void pcf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message) + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg) { OpenAPI_nf_profile_t *NFProfile = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(nf_instance); client = nf_instance->client; ogs_assert(client); - NFProfile = message->NFProfile; + NFProfile = recvmsg->NFProfile; if (!NFProfile) { ogs_error("No NFProfile"); return; @@ -42,17 +42,17 @@ void pcf_nnrf_handle_nf_register( } void pcf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message) + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg) { OpenAPI_subscription_data_t *SubscriptionData = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(subscription); client = subscription->client; ogs_assert(client); - SubscriptionData = message->SubscriptionData; + SubscriptionData = recvmsg->SubscriptionData; if (!SubscriptionData) { ogs_error("No SubscriptionData"); return; @@ -66,12 +66,11 @@ void pcf_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { -#define VALIDITY_MARGIN (5LL * OGS_USEC_PER_SEC) /* 5 seconds */ -#define VALIDITY_MINIMUM (3600LL * OGS_USEC_PER_SEC) /* 3600 seconds */ +#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() - VALIDITY_MARGIN; + duration = time - ogs_time_now(); if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %lld seconds", subscription->id, @@ -89,79 +88,103 @@ void pcf_nnrf_handle_nf_status_subscribe( } bool pcf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { - ogs_sbi_response_t *response = NULL; - OpenAPI_notification_data_t *NotificationData = NULL; - OpenAPI_nf_profile_t *NFProfile = NULL; - ogs_sbi_nf_instance_t *nf_instance = NULL; + int rv; bool handled; - ogs_assert(stream); - ogs_assert(message); + ogs_sbi_response_t *response = NULL; + OpenAPI_notification_data_t *NotificationData = NULL; + ogs_sbi_nf_instance_t *nf_instance = NULL; - NotificationData = message->NotificationData; + ogs_sbi_message_t message; + ogs_sbi_header_t header; + + ogs_assert(stream); + ogs_assert(recvmsg); + + NotificationData = recvmsg->NotificationData; if (!NotificationData) { ogs_error("No NotificationData"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NotificationData", NULL); + recvmsg, "No NotificationData", NULL); return false; } - NFProfile = NotificationData->nf_profile; - if (!NFProfile) { - ogs_error("No NFProfile"); + if (!NotificationData->nf_instance_uri) { + ogs_error("No nfInstanceUri"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", NULL); + recvmsg, "No nfInstanceUri", NULL); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + memset(&header, 0, sizeof(header)); + header.uri = NotificationData->nf_instance_uri; + + rv = ogs_sbi_parse_header(&message, &header); + if (rv != OGS_OK) { + ogs_error("Cannot parse nfInstanceUri [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + if (!message.h.resource.component[1]) { + ogs_error("No nfInstanceId [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); + ogs_sbi_header_free(&header); return false; } - if (NF_INSTANCE_IS_SELF(NFProfile->nf_instance_id)) { - ogs_warn("The notification is not allowed [%s]", - NFProfile->nf_instance_id); + if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) { + ogs_warn("[%s] The notification is not allowed", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN, - message, "The notification is not allowed", - NFProfile->nf_instance_id); + recvmsg, "The notification is not allowed", + message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } if (NotificationData->event == OpenAPI_notification_event_type_NF_REGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + OpenAPI_nf_profile_t *NFProfile = NULL; + + NFProfile = NotificationData->nf_profile; + if (!NFProfile) { + ogs_error("No NFProfile"); + ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No NFProfile", NULL); + ogs_sbi_header_free(&header); + return false; + } + + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (!nf_instance) { - nf_instance = ogs_sbi_nf_instance_add(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_add( + message.h.resource.component[1]); ogs_assert(nf_instance); pcf_nf_fsm_init(nf_instance); ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id); + } else { OGS_FSM_TRAN(&nf_instance->sm, pcf_nf_state_registered); ogs_fsm_dispatch(&nf_instance->sm, NULL); ogs_warn("[%s] (NRF-notify) NF has already been added", - NFProfile->nf_instance_id); + message.h.resource.component[1]); + } handled = ogs_sbi_nnrf_handle_nf_profile( - nf_instance, NFProfile, stream, message); + nf_instance, NFProfile, stream, recvmsg); if (!handled) { PCF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } @@ -172,21 +195,24 @@ bool pcf_nnrf_handle_nf_status_notify( ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Cannot find NF EndPoint", nf_instance->id); + recvmsg, "Cannot find NF EndPoint", nf_instance->id); PCF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (nf_instance) { PCF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); } else { - ogs_warn("[%s] (NRF-notify) Not found", NFProfile->nf_instance_id); + ogs_warn("[%s] (NRF-notify) Not found", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, - OGS_SBI_HTTP_STATUS_NOT_FOUND, - message, "Not found", message->h.resource.component[1]); + OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Not found", message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } } else { @@ -195,20 +221,22 @@ bool pcf_nnrf_handle_nf_status_notify( ogs_error("Not supported event [%d:%s]", NotificationData->event, eventstr ? eventstr : "Unknown"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Not supported event", + recvmsg, "Not supported event", eventstr ? eventstr : "Unknown"); + ogs_sbi_header_free(&header); return false; } - response = ogs_sbi_build_response(message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); + ogs_sbi_header_free(&header); return true; } void pcf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message) + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg) { ogs_sbi_object_t *sbi_object = NULL; pcf_ue_t *pcf_ue = NULL; @@ -225,9 +253,9 @@ void pcf_nnrf_handle_nf_discover( ogs_assert(sbi_object); stream = xact->assoc_stream; ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - SearchResult = message->SearchResult; + SearchResult = recvmsg->SearchResult; if (!SearchResult) { ogs_error("No SearchResult"); return; diff --git a/src/pcf/nnrf-handler.h b/src/pcf/nnrf-handler.h index 3d4b23735..c3965ce3a 100644 --- a/src/pcf/nnrf-handler.h +++ b/src/pcf/nnrf-handler.h @@ -27,15 +27,15 @@ extern "C" { #endif void pcf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message); + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg); void pcf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message); + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg); bool pcf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); void pcf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message); + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); #ifdef __cplusplus } diff --git a/src/pcf/pcf-sm.c b/src/pcf/pcf-sm.c index d7127074c..ef9f5cac9 100644 --- a/src/pcf/pcf-sm.c +++ b/src/pcf/pcf-sm.c @@ -413,11 +413,12 @@ void pcf_state_operational(ogs_fsm_t *s, pcf_event_t *e) subscription = e->sbi.data; ogs_assert(subscription); + ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, + pcf_self()->nf_type, subscription->req_nf_instance_id, + subscription->subscr_cond.nf_type); + ogs_info("[%s] Subscription validity expired", subscription->id); ogs_sbi_subscription_remove(subscription); - - ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, - pcf_self()->nf_type, subscription->nf_instance_id); break; case PCF_TIMER_SBI_CLIENT_WAIT: diff --git a/src/smf/nf-sm.c b/src/smf/nf-sm.c index d076178f3..417422aa8 100644 --- a/src/smf/nf-sm.c +++ b/src/smf/nf-sm.c @@ -211,7 +211,13 @@ void smf_nf_state_registered(ogs_fsm_t *s, smf_event_t *e) } ogs_nnrf_nfm_send_nf_status_subscribe(client, - smf_self()->nf_type, nf_instance->id); + smf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_AMF); + ogs_nnrf_nfm_send_nf_status_subscribe(client, + smf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_UDM); + ogs_nnrf_nfm_send_nf_status_subscribe(client, + smf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_PCF); + ogs_nnrf_nfm_send_nf_status_subscribe(client, + smf_self()->nf_type, nf_instance->id, OpenAPI_nf_type_UPF); } break; diff --git a/src/smf/nnrf-handler.c b/src/smf/nnrf-handler.c index e9aa5627e..ef8086e10 100644 --- a/src/smf/nnrf-handler.c +++ b/src/smf/nnrf-handler.c @@ -21,17 +21,17 @@ #include "nnrf-handler.h" void smf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message) + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg) { OpenAPI_nf_profile_t *NFProfile = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(nf_instance); client = nf_instance->client; ogs_assert(client); - NFProfile = message->NFProfile; + NFProfile = recvmsg->NFProfile; if (!NFProfile) { ogs_error("No NFProfile"); return; @@ -42,17 +42,17 @@ void smf_nnrf_handle_nf_register( } void smf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message) + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg) { OpenAPI_subscription_data_t *SubscriptionData = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(subscription); client = subscription->client; ogs_assert(client); - SubscriptionData = message->SubscriptionData; + SubscriptionData = recvmsg->SubscriptionData; if (!SubscriptionData) { ogs_error("No SubscriptionData"); return; @@ -66,12 +66,11 @@ void smf_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { -#define VALIDITY_MARGIN (5LL * OGS_USEC_PER_SEC) /* 5 seconds */ -#define VALIDITY_MINIMUM (3600LL * OGS_USEC_PER_SEC) /* 3600 seconds */ +#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() - VALIDITY_MARGIN; + duration = time - ogs_time_now(); if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %lld seconds", subscription->id, @@ -89,79 +88,103 @@ void smf_nnrf_handle_nf_status_subscribe( } bool smf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { - ogs_sbi_response_t *response = NULL; - OpenAPI_notification_data_t *NotificationData = NULL; - OpenAPI_nf_profile_t *NFProfile = NULL; - ogs_sbi_nf_instance_t *nf_instance = NULL; + int rv; bool handled; - ogs_assert(stream); - ogs_assert(message); + ogs_sbi_response_t *response = NULL; + OpenAPI_notification_data_t *NotificationData = NULL; + ogs_sbi_nf_instance_t *nf_instance = NULL; - NotificationData = message->NotificationData; + ogs_sbi_message_t message; + ogs_sbi_header_t header; + + ogs_assert(stream); + ogs_assert(recvmsg); + + NotificationData = recvmsg->NotificationData; if (!NotificationData) { ogs_error("No NotificationData"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NotificationData", NULL); + recvmsg, "No NotificationData", NULL); return false; } - NFProfile = NotificationData->nf_profile; - if (!NFProfile) { - ogs_error("No NFProfile"); + if (!NotificationData->nf_instance_uri) { + ogs_error("No nfInstanceUri"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", NULL); + recvmsg, "No nfInstanceUri", NULL); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + memset(&header, 0, sizeof(header)); + header.uri = NotificationData->nf_instance_uri; + + rv = ogs_sbi_parse_header(&message, &header); + if (rv != OGS_OK) { + ogs_error("Cannot parse nfInstanceUri [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + if (!message.h.resource.component[1]) { + ogs_error("No nfInstanceId [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); + ogs_sbi_header_free(&header); return false; } - if (NF_INSTANCE_IS_SELF(NFProfile->nf_instance_id)) { + if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) { ogs_warn("[%s] The notification is not allowed", - NFProfile->nf_instance_id); + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN, - message, "The notification is not allowed", - NFProfile->nf_instance_id); + recvmsg, "The notification is not allowed", + message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } if (NotificationData->event == OpenAPI_notification_event_type_NF_REGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + OpenAPI_nf_profile_t *NFProfile = NULL; + + NFProfile = NotificationData->nf_profile; + if (!NFProfile) { + ogs_error("No NFProfile"); + ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No NFProfile", NULL); + ogs_sbi_header_free(&header); + return false; + } + + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (!nf_instance) { - nf_instance = ogs_sbi_nf_instance_add(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_add( + message.h.resource.component[1]); ogs_assert(nf_instance); smf_nf_fsm_init(nf_instance); ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id); + } else { OGS_FSM_TRAN(&nf_instance->sm, smf_nf_state_registered); ogs_fsm_dispatch(&nf_instance->sm, NULL); ogs_warn("[%s] (NRF-notify) NF has already been added", - NFProfile->nf_instance_id); + message.h.resource.component[1]); + } handled = ogs_sbi_nnrf_handle_nf_profile( - nf_instance, NFProfile, stream, message); + nf_instance, NFProfile, stream, recvmsg); if (!handled) { SMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } @@ -172,21 +195,24 @@ bool smf_nnrf_handle_nf_status_notify( ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Cannot find NF EndPoint", nf_instance->id); + recvmsg, "Cannot find NF EndPoint", nf_instance->id); SMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (nf_instance) { SMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); } else { - ogs_warn("[%s] (NRF-notify) Not found", NFProfile->nf_instance_id); + ogs_warn("[%s] (NRF-notify) Not found", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, - OGS_SBI_HTTP_STATUS_NOT_FOUND, - message, "Not found", message->h.resource.component[1]); + OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Not found", message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } } else { @@ -195,20 +221,22 @@ bool smf_nnrf_handle_nf_status_notify( ogs_error("Not supported event [%d:%s]", NotificationData->event, eventstr ? eventstr : "Unknown"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Not supported event", + recvmsg, "Not supported event", eventstr ? eventstr : "Unknown"); + ogs_sbi_header_free(&header); return false; } - response = ogs_sbi_build_response(message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); + ogs_sbi_header_free(&header); return true; } void smf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message) + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg) { ogs_sbi_object_t *sbi_object = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL; @@ -223,9 +251,9 @@ void smf_nnrf_handle_nf_discover( ogs_assert(sbi_object); stream = xact->assoc_stream; ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - SearchResult = message->SearchResult; + SearchResult = recvmsg->SearchResult; if (!SearchResult) { ogs_error("No SearchResult"); return; diff --git a/src/smf/nnrf-handler.h b/src/smf/nnrf-handler.h index 7a537f6f6..431b6c933 100644 --- a/src/smf/nnrf-handler.h +++ b/src/smf/nnrf-handler.h @@ -27,15 +27,15 @@ extern "C" { #endif void smf_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message); + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg); void smf_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message); + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg); bool smf_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); void smf_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message); + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); #ifdef __cplusplus } diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index f34418e4c..939cdc933 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -581,11 +581,12 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) subscription = e->sbi.data; ogs_assert(subscription); + ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, + smf_self()->nf_type, subscription->req_nf_instance_id, + subscription->subscr_cond.nf_type); + ogs_info("Subscription validity expired [%s]", subscription->id); ogs_sbi_subscription_remove(subscription); - - ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, - smf_self()->nf_type, subscription->nf_instance_id); break; case SMF_TIMER_SBI_CLIENT_WAIT: diff --git a/src/udm/nf-sm.c b/src/udm/nf-sm.c index aa229b4d1..d5e0437f7 100644 --- a/src/udm/nf-sm.c +++ b/src/udm/nf-sm.c @@ -210,7 +210,7 @@ void udm_nf_state_registered(ogs_fsm_t *s, udm_event_t *e) } ogs_nnrf_nfm_send_nf_status_subscribe(client, - udm_self()->nf_type, nf_instance->id); + udm_self()->nf_type, nf_instance->id, OpenAPI_nf_type_UDR); } break; diff --git a/src/udm/nnrf-handler.c b/src/udm/nnrf-handler.c index 19468cd69..0faa0f615 100644 --- a/src/udm/nnrf-handler.c +++ b/src/udm/nnrf-handler.c @@ -21,17 +21,17 @@ #include "nnrf-handler.h" void udm_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message) + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg) { OpenAPI_nf_profile_t *NFProfile = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(nf_instance); client = nf_instance->client; ogs_assert(client); - NFProfile = message->NFProfile; + NFProfile = recvmsg->NFProfile; if (!NFProfile) { ogs_error("No NFProfile"); return; @@ -42,17 +42,17 @@ void udm_nnrf_handle_nf_register( } void udm_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message) + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg) { OpenAPI_subscription_data_t *SubscriptionData = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(subscription); client = subscription->client; ogs_assert(client); - SubscriptionData = message->SubscriptionData; + SubscriptionData = recvmsg->SubscriptionData; if (!SubscriptionData) { ogs_error("No SubscriptionData"); return; @@ -66,12 +66,11 @@ void udm_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { -#define VALIDITY_MARGIN (5LL * OGS_USEC_PER_SEC) /* 5 seconds */ -#define VALIDITY_MINIMUM (3600LL * OGS_USEC_PER_SEC) /* 3600 seconds */ +#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() - VALIDITY_MARGIN; + duration = time - ogs_time_now(); if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %lld seconds", subscription->id, @@ -89,79 +88,103 @@ void udm_nnrf_handle_nf_status_subscribe( } bool udm_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { - ogs_sbi_response_t *response = NULL; - OpenAPI_notification_data_t *NotificationData = NULL; - OpenAPI_nf_profile_t *NFProfile = NULL; - ogs_sbi_nf_instance_t *nf_instance = NULL; + int rv; bool handled; - ogs_assert(stream); - ogs_assert(message); + ogs_sbi_response_t *response = NULL; + OpenAPI_notification_data_t *NotificationData = NULL; + ogs_sbi_nf_instance_t *nf_instance = NULL; - NotificationData = message->NotificationData; + ogs_sbi_message_t message; + ogs_sbi_header_t header; + + ogs_assert(stream); + ogs_assert(recvmsg); + + NotificationData = recvmsg->NotificationData; if (!NotificationData) { ogs_error("No NotificationData"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NotificationData", NULL); + recvmsg, "No NotificationData", NULL); return false; } - NFProfile = NotificationData->nf_profile; - if (!NFProfile) { - ogs_error("No NFProfile"); + if (!NotificationData->nf_instance_uri) { + ogs_error("No nfInstanceUri"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", NULL); + recvmsg, "No nfInstanceUri", NULL); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + memset(&header, 0, sizeof(header)); + header.uri = NotificationData->nf_instance_uri; + + rv = ogs_sbi_parse_header(&message, &header); + if (rv != OGS_OK) { + ogs_error("Cannot parse nfInstanceUri [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + if (!message.h.resource.component[1]) { + ogs_error("No nfInstanceId [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); + ogs_sbi_header_free(&header); return false; } - if (NF_INSTANCE_IS_SELF(NFProfile->nf_instance_id)) { - ogs_warn("The notification is not allowed [%s]", - NFProfile->nf_instance_id); + if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) { + ogs_warn("[%s] The notification is not allowed", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN, - message, "The notification is not allowed", - NFProfile->nf_instance_id); + recvmsg, "The notification is not allowed", + message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } if (NotificationData->event == OpenAPI_notification_event_type_NF_REGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + OpenAPI_nf_profile_t *NFProfile = NULL; + + NFProfile = NotificationData->nf_profile; + if (!NFProfile) { + ogs_error("No NFProfile"); + ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No NFProfile", NULL); + ogs_sbi_header_free(&header); + return false; + } + + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (!nf_instance) { - nf_instance = ogs_sbi_nf_instance_add(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_add( + message.h.resource.component[1]); ogs_assert(nf_instance); udm_nf_fsm_init(nf_instance); ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id); + } else { OGS_FSM_TRAN(&nf_instance->sm, udm_nf_state_registered); ogs_fsm_dispatch(&nf_instance->sm, NULL); ogs_warn("[%s] (NRF-notify) NF has already been added", - NFProfile->nf_instance_id); + message.h.resource.component[1]); + } handled = ogs_sbi_nnrf_handle_nf_profile( - nf_instance, NFProfile, stream, message); + nf_instance, NFProfile, stream, recvmsg); if (!handled) { UDM_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } @@ -172,21 +195,24 @@ bool udm_nnrf_handle_nf_status_notify( ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Cannot find NF EndPoint", nf_instance->id); + recvmsg, "Cannot find NF EndPoint", nf_instance->id); UDM_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (nf_instance) { UDM_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); } else { - ogs_warn("[%s] (NRF-notify) Not found", NFProfile->nf_instance_id); + ogs_warn("[%s] (NRF-notify) Not found", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, - OGS_SBI_HTTP_STATUS_NOT_FOUND, - message, "Not found", message->h.resource.component[1]); + OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Not found", message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } } else { @@ -195,20 +221,22 @@ bool udm_nnrf_handle_nf_status_notify( ogs_error("Not supported event [%d:%s]", NotificationData->event, eventstr ? eventstr : "Unknown"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Not supported event", + recvmsg, "Not supported event", eventstr ? eventstr : "Unknown"); + ogs_sbi_header_free(&header); return false; } - response = ogs_sbi_build_response(message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); + ogs_sbi_header_free(&header); return true; } void udm_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message) + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg) { ogs_sbi_object_t *sbi_object = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL; @@ -223,9 +251,9 @@ void udm_nnrf_handle_nf_discover( ogs_assert(sbi_object); stream = xact->assoc_stream; ogs_assert(stream); - ogs_assert(message); + ogs_assert(recvmsg); - SearchResult = message->SearchResult; + SearchResult = recvmsg->SearchResult; if (!SearchResult) { ogs_error("No SearchResult"); return; diff --git a/src/udm/nnrf-handler.h b/src/udm/nnrf-handler.h index a628b7a86..2c69040c5 100644 --- a/src/udm/nnrf-handler.h +++ b/src/udm/nnrf-handler.h @@ -27,15 +27,15 @@ extern "C" { #endif void udm_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message); + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg); void udm_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message); + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg); bool udm_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); void udm_nnrf_handle_nf_discover( - ogs_sbi_xact_t *xact, ogs_sbi_message_t *message); + ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); #ifdef __cplusplus } diff --git a/src/udm/udm-sm.c b/src/udm/udm-sm.c index e09135c72..4754ccbf5 100644 --- a/src/udm/udm-sm.c +++ b/src/udm/udm-sm.c @@ -363,11 +363,12 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e) subscription = e->sbi.data; ogs_assert(subscription); + ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, + udm_self()->nf_type, subscription->req_nf_instance_id, + subscription->subscr_cond.nf_type); + ogs_info("[%s] Subscription validity expired", subscription->id); ogs_sbi_subscription_remove(subscription); - - ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, - udm_self()->nf_type, subscription->nf_instance_id); break; case UDM_TIMER_SBI_CLIENT_WAIT: diff --git a/src/udr/nf-sm.c b/src/udr/nf-sm.c index 0bfa978a5..2d063640b 100644 --- a/src/udr/nf-sm.c +++ b/src/udr/nf-sm.c @@ -208,9 +208,6 @@ void udr_nf_state_registered(ogs_fsm_t *s, udr_event_t *e) nf_instance->time.heartbeat_interval + ogs_app()->time.nf_instance.no_heartbeat_margin)); } - - ogs_nnrf_nfm_send_nf_status_subscribe(client, - udr_self()->nf_type, nf_instance->id); } break; diff --git a/src/udr/nnrf-handler.c b/src/udr/nnrf-handler.c index 7ec96899f..ee3c3cc58 100644 --- a/src/udr/nnrf-handler.c +++ b/src/udr/nnrf-handler.c @@ -21,17 +21,17 @@ #include "nnrf-handler.h" void udr_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message) + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg) { OpenAPI_nf_profile_t *NFProfile = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(nf_instance); client = nf_instance->client; ogs_assert(client); - NFProfile = message->NFProfile; + NFProfile = recvmsg->NFProfile; if (!NFProfile) { ogs_error("No NFProfile"); return; @@ -42,17 +42,17 @@ void udr_nnrf_handle_nf_register( } void udr_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message) + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg) { OpenAPI_subscription_data_t *SubscriptionData = NULL; ogs_sbi_client_t *client = NULL; - ogs_assert(message); + ogs_assert(recvmsg); ogs_assert(subscription); client = subscription->client; ogs_assert(client); - SubscriptionData = message->SubscriptionData; + SubscriptionData = recvmsg->SubscriptionData; if (!SubscriptionData) { ogs_error("No SubscriptionData"); return; @@ -66,12 +66,11 @@ void udr_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { -#define VALIDITY_MARGIN (5LL * OGS_USEC_PER_SEC) /* 5 seconds */ -#define VALIDITY_MINIMUM (3600LL * OGS_USEC_PER_SEC) /* 3600 seconds */ +#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() - VALIDITY_MARGIN; + duration = time - ogs_time_now(); if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %lld seconds", subscription->id, @@ -89,79 +88,103 @@ void udr_nnrf_handle_nf_status_subscribe( } bool udr_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { - ogs_sbi_response_t *response = NULL; - OpenAPI_notification_data_t *NotificationData = NULL; - OpenAPI_nf_profile_t *NFProfile = NULL; - ogs_sbi_nf_instance_t *nf_instance = NULL; + int rv; bool handled; - ogs_assert(stream); - ogs_assert(message); + ogs_sbi_response_t *response = NULL; + OpenAPI_notification_data_t *NotificationData = NULL; + ogs_sbi_nf_instance_t *nf_instance = NULL; - NotificationData = message->NotificationData; + ogs_sbi_message_t message; + ogs_sbi_header_t header; + + ogs_assert(stream); + ogs_assert(recvmsg); + + NotificationData = recvmsg->NotificationData; if (!NotificationData) { ogs_error("No NotificationData"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NotificationData", NULL); + recvmsg, "No NotificationData", NULL); return false; } - NFProfile = NotificationData->nf_profile; - if (!NFProfile) { - ogs_error("No NFProfile"); + if (!NotificationData->nf_instance_uri) { + ogs_error("No nfInstanceUri"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", NULL); + recvmsg, "No nfInstanceUri", NULL); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + memset(&header, 0, sizeof(header)); + header.uri = NotificationData->nf_instance_uri; + + rv = ogs_sbi_parse_header(&message, &header); + if (rv != OGS_OK) { + ogs_error("Cannot parse nfInstanceUri [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); return false; } - if (!NFProfile->nf_instance_id) { - ogs_error("No NFProfile.NFInstanceId"); + if (!message.h.resource.component[1]) { + ogs_error("No nfInstanceId [%s]", header.uri); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "No NFProfile", "NFInstanceId"); + recvmsg, "Cannot parse nfInstanceUri", header.uri); + ogs_sbi_header_free(&header); return false; } - if (NF_INSTANCE_IS_SELF(NFProfile->nf_instance_id)) { - ogs_warn("The notification is not allowed [%s]", - NFProfile->nf_instance_id); + if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) { + ogs_warn("[%s] The notification is not allowed", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN, - message, "The notification is not allowed", - NFProfile->nf_instance_id); + recvmsg, "The notification is not allowed", + message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } if (NotificationData->event == OpenAPI_notification_event_type_NF_REGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + OpenAPI_nf_profile_t *NFProfile = NULL; + + NFProfile = NotificationData->nf_profile; + if (!NFProfile) { + ogs_error("No NFProfile"); + ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No NFProfile", NULL); + ogs_sbi_header_free(&header); + return false; + } + + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (!nf_instance) { - nf_instance = ogs_sbi_nf_instance_add(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_add( + message.h.resource.component[1]); ogs_assert(nf_instance); udr_nf_fsm_init(nf_instance); ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id); + } else { OGS_FSM_TRAN(&nf_instance->sm, udr_nf_state_registered); ogs_fsm_dispatch(&nf_instance->sm, NULL); ogs_warn("[%s] (NRF-notify) NF has already been added", - NFProfile->nf_instance_id); + message.h.resource.component[1]); + } handled = ogs_sbi_nnrf_handle_nf_profile( - nf_instance, NFProfile, stream, message); + nf_instance, NFProfile, stream, recvmsg); if (!handled) { UDR_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } @@ -172,21 +195,24 @@ bool udr_nnrf_handle_nf_status_notify( ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Cannot find NF EndPoint", nf_instance->id); + recvmsg, "Cannot find NF EndPoint", nf_instance->id); UDR_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); + ogs_sbi_header_free(&header); return false; } } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { - nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); + nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]); if (nf_instance) { UDR_NF_INSTANCE_CLEAR("NRF-notify", nf_instance); } else { - ogs_warn("[%s] (NRF-notify) Not found", NFProfile->nf_instance_id); + ogs_warn("[%s] (NRF-notify) Not found", + message.h.resource.component[1]); ogs_sbi_server_send_error(stream, - OGS_SBI_HTTP_STATUS_NOT_FOUND, - message, "Not found", message->h.resource.component[1]); + OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Not found", message.h.resource.component[1]); + ogs_sbi_header_free(&header); return false; } } else { @@ -195,14 +221,16 @@ bool udr_nnrf_handle_nf_status_notify( ogs_error("Not supported event [%d:%s]", NotificationData->event, eventstr ? eventstr : "Unknown"); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, "Not supported event", + recvmsg, "Not supported event", eventstr ? eventstr : "Unknown"); + ogs_sbi_header_free(&header); return false; } - response = ogs_sbi_build_response(message, OGS_SBI_HTTP_STATUS_NO_CONTENT); + response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT); ogs_assert(response); ogs_sbi_server_send_response(stream, response); + ogs_sbi_header_free(&header); return true; } diff --git a/src/udr/nnrf-handler.h b/src/udr/nnrf-handler.h index a7890bf1b..a257e5119 100644 --- a/src/udr/nnrf-handler.h +++ b/src/udr/nnrf-handler.h @@ -27,12 +27,12 @@ extern "C" { #endif void udr_nnrf_handle_nf_register( - ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *message); + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg); void udr_nnrf_handle_nf_status_subscribe( - ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *message); + ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg); bool udr_nnrf_handle_nf_status_notify( - ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); + ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg); #ifdef __cplusplus } diff --git a/src/udr/udr-sm.c b/src/udr/udr-sm.c index d931dff83..84630bcb0 100644 --- a/src/udr/udr-sm.c +++ b/src/udr/udr-sm.c @@ -288,11 +288,12 @@ void udr_state_operational(ogs_fsm_t *s, udr_event_t *e) subscription = e->sbi.data; ogs_assert(subscription); + ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, + udr_self()->nf_type, subscription->req_nf_instance_id, + subscription->subscr_cond.nf_type); + ogs_info("[%s] Subscription validity expired", subscription->id); ogs_sbi_subscription_remove(subscription); - - ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client, - udr_self()->nf_type, subscription->nf_instance_id); break; default: diff --git a/tests/app/5gc-init.c b/tests/app/5gc-init.c index 8ff409955..3c31e16ca 100644 --- a/tests/app/5gc-init.c +++ b/tests/app/5gc-init.c @@ -20,13 +20,13 @@ #include "test-app.h" static ogs_thread_t *nrf_thread = NULL; +static ogs_thread_t *upf_thread = NULL; +static ogs_thread_t *smf_thread = NULL; +static ogs_thread_t *amf_thread = NULL; static ogs_thread_t *ausf_thread = NULL; static ogs_thread_t *udm_thread = NULL; static ogs_thread_t *pcf_thread = NULL; static ogs_thread_t *udr_thread = NULL; -static ogs_thread_t *upf_thread = NULL; -static ogs_thread_t *smf_thread = NULL; -static ogs_thread_t *amf_thread = NULL; int app_initialize(const char *const argv[]) { @@ -51,15 +51,6 @@ int app_initialize(const char *const argv[]) if (ogs_app()->parameter.no_nrf == 0) nrf_thread = test_child_create("nrf", argv_out); - if (ogs_app()->parameter.no_udr == 0) - udr_thread = test_child_create("udr", argv_out); - if (ogs_app()->parameter.no_pcf == 0) - pcf_thread = test_child_create("pcf", argv_out); - if (ogs_app()->parameter.no_udm == 0) - udm_thread = test_child_create("udm", argv_out); - if (ogs_app()->parameter.no_ausf == 0) - ausf_thread = test_child_create("ausf", argv_out); - if (ogs_app()->parameter.no_upf == 0) upf_thread = test_child_create("upf", argv_out); if (ogs_app()->parameter.no_smf == 0) @@ -68,12 +59,21 @@ int app_initialize(const char *const argv[]) if (ogs_app()->parameter.no_amf == 0) amf_thread = test_child_create("amf", argv_out); + if (ogs_app()->parameter.no_ausf == 0) + ausf_thread = test_child_create("ausf", argv_out); + if (ogs_app()->parameter.no_udm == 0) + udm_thread = test_child_create("udm", argv_out); + if (ogs_app()->parameter.no_pcf == 0) + pcf_thread = test_child_create("pcf", argv_out); + if (ogs_app()->parameter.no_udr == 0) + udr_thread = test_child_create("udr", argv_out); + /* * Wait for all sockets listening * * If freeDiameter is not used, it uses a delay of less than 4 seconds. */ - ogs_msleep(3000); + ogs_msleep(5000); return OGS_OK;; } @@ -85,10 +85,10 @@ void app_terminate(void) if (smf_thread) ogs_thread_destroy(smf_thread); if (upf_thread) ogs_thread_destroy(upf_thread); - if (ausf_thread) ogs_thread_destroy(ausf_thread); - if (udm_thread) ogs_thread_destroy(udm_thread); - if (pcf_thread) ogs_thread_destroy(pcf_thread); if (udr_thread) ogs_thread_destroy(udr_thread); + if (pcf_thread) ogs_thread_destroy(pcf_thread); + if (udm_thread) ogs_thread_destroy(udm_thread); + if (ausf_thread) ogs_thread_destroy(ausf_thread); if (nrf_thread) ogs_thread_destroy(nrf_thread); } diff --git a/tests/app/app-init.c b/tests/app/app-init.c index 9b3afd6fd..cda194518 100644 --- a/tests/app/app-init.c +++ b/tests/app/app-init.c @@ -22,16 +22,16 @@ static ogs_thread_t *nrf_thread = NULL; static ogs_thread_t *pcrf_thread = NULL; static ogs_thread_t *hss_thread = NULL; -static ogs_thread_t *ausf_thread = NULL; -static ogs_thread_t *udm_thread = NULL; -static ogs_thread_t *pcf_thread = NULL; -static ogs_thread_t *udr_thread = NULL; static ogs_thread_t *upf_thread = NULL; static ogs_thread_t *sgwc_thread = NULL; static ogs_thread_t *sgwu_thread = NULL; static ogs_thread_t *smf_thread = NULL; static ogs_thread_t *mme_thread = NULL; static ogs_thread_t *amf_thread = NULL; +static ogs_thread_t *ausf_thread = NULL; +static ogs_thread_t *udm_thread = NULL; +static ogs_thread_t *pcf_thread = NULL; +static ogs_thread_t *udr_thread = NULL; int app_initialize(const char *const argv[]) { @@ -60,15 +60,6 @@ int app_initialize(const char *const argv[]) if (ogs_app()->parameter.no_pcrf == 0) pcrf_thread = test_child_create("pcrf", argv_out); - if (ogs_app()->parameter.no_udr == 0) - udr_thread = test_child_create("udr", argv_out); - if (ogs_app()->parameter.no_pcf == 0) - pcf_thread = test_child_create("pcf", argv_out); - if (ogs_app()->parameter.no_udm == 0) - udm_thread = test_child_create("udm", argv_out); - if (ogs_app()->parameter.no_ausf == 0) - ausf_thread = test_child_create("ausf", argv_out); - if (ogs_app()->parameter.no_upf == 0) upf_thread = test_child_create("upf", argv_out); if (ogs_app()->parameter.no_sgwu == 0) @@ -84,6 +75,15 @@ int app_initialize(const char *const argv[]) if (ogs_app()->parameter.no_amf == 0) amf_thread = test_child_create("amf", argv_out); + if (ogs_app()->parameter.no_ausf == 0) + ausf_thread = test_child_create("ausf", argv_out); + if (ogs_app()->parameter.no_udm == 0) + udm_thread = test_child_create("udm", argv_out); + if (ogs_app()->parameter.no_pcf == 0) + pcf_thread = test_child_create("pcf", argv_out); + if (ogs_app()->parameter.no_udr == 0) + udr_thread = test_child_create("udr", argv_out); + /* * Wait for all sockets listening * @@ -105,10 +105,10 @@ void app_terminate(void) if (sgwu_thread) ogs_thread_destroy(sgwu_thread); if (upf_thread) ogs_thread_destroy(upf_thread); - if (ausf_thread) ogs_thread_destroy(ausf_thread); - if (udm_thread) ogs_thread_destroy(udm_thread); - if (pcf_thread) ogs_thread_destroy(pcf_thread); if (udr_thread) ogs_thread_destroy(udr_thread); + if (pcf_thread) ogs_thread_destroy(pcf_thread); + if (udm_thread) ogs_thread_destroy(udm_thread); + if (ausf_thread) ogs_thread_destroy(ausf_thread); if (hss_thread) ogs_thread_destroy(hss_thread); if (pcrf_thread) ogs_thread_destroy(pcrf_thread); diff --git a/tests/unit/sbi-message-test.c b/tests/unit/sbi-message-test.c index 98025819f..83e3252dc 100644 --- a/tests/unit/sbi-message-test.c +++ b/tests/unit/sbi-message-test.c @@ -344,6 +344,146 @@ static void sbi_message_test3(abts_case *tc, void *data) OpenAPI_nrf_info_free(nrf_info2); } +static void sbi_message_test4(abts_case *tc, void *data) +{ + ogs_time_t t; + struct tm tm; + bool rc; + + rc = ogs_sbi_time_from_string(&t, "1985-04-12T23:20:50.52"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 85, tm.tm_year); + ABTS_INT_EQUAL(tc, 3, tm.tm_mon); + ABTS_INT_EQUAL(tc, 12, tm.tm_mday); + ABTS_INT_EQUAL(tc, 23, tm.tm_hour); + ABTS_INT_EQUAL(tc, 20, tm.tm_min); + ABTS_INT_EQUAL(tc, 50, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 482196050520000); + + rc = ogs_sbi_time_from_string(&t, "1996-12-19T16:39:57-0800"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 96, tm.tm_year); + ABTS_INT_EQUAL(tc, 11, tm.tm_mon); + ABTS_INT_EQUAL(tc, 20, tm.tm_mday); + ABTS_INT_EQUAL(tc, 0, tm.tm_hour); + ABTS_INT_EQUAL(tc, 39, tm.tm_min); + ABTS_INT_EQUAL(tc, 57, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 851042397000000); + + tm.tm_mday = 19; + tm.tm_hour = 16; + tm.tm_gmtoff = -28800; + + rc = ogs_sbi_time_from_string(&t, "1996-12-19T16:39:57-08:00"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 96, tm.tm_year); + ABTS_INT_EQUAL(tc, 11, tm.tm_mon); + ABTS_INT_EQUAL(tc, 20, tm.tm_mday); + ABTS_INT_EQUAL(tc, 0, tm.tm_hour); + ABTS_INT_EQUAL(tc, 39, tm.tm_min); + ABTS_INT_EQUAL(tc, 57, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 851042397000000); + + rc = ogs_sbi_time_from_string(&t, "1990-12-31T23:59:60Z"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 91, tm.tm_year); + ABTS_INT_EQUAL(tc, 0, tm.tm_mon); + ABTS_INT_EQUAL(tc, 1, tm.tm_mday); + ABTS_INT_EQUAL(tc, 0, tm.tm_hour); + ABTS_INT_EQUAL(tc, 0, tm.tm_min); + ABTS_INT_EQUAL(tc, 0, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 662688000000000); + + rc = ogs_sbi_time_from_string(&t, "1990-12-31T15:59:60-0800"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 91, tm.tm_year); + ABTS_INT_EQUAL(tc, 0, tm.tm_mon); + ABTS_INT_EQUAL(tc, 1, tm.tm_mday); + ABTS_INT_EQUAL(tc, 0, tm.tm_hour); + ABTS_INT_EQUAL(tc, 0, tm.tm_min); + ABTS_INT_EQUAL(tc, 0, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 662688000000000); + + rc = ogs_sbi_time_from_string(&t, "1990-12-31T15:59:60-08:00"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 91, tm.tm_year); + ABTS_INT_EQUAL(tc, 0, tm.tm_mon); + ABTS_INT_EQUAL(tc, 1, tm.tm_mday); + ABTS_INT_EQUAL(tc, 0, tm.tm_hour); + ABTS_INT_EQUAL(tc, 0, tm.tm_min); + ABTS_INT_EQUAL(tc, 0, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 662688000000000); + + rc = ogs_sbi_time_from_string(&t, "1987-01-01T12:00:27.87+0020"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 87, tm.tm_year); + ABTS_INT_EQUAL(tc, 0, tm.tm_mon); + ABTS_INT_EQUAL(tc, 1, tm.tm_mday); + ABTS_INT_EQUAL(tc, 11, tm.tm_hour); + ABTS_INT_EQUAL(tc, 40, tm.tm_min); + ABTS_INT_EQUAL(tc, 27, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 536499627870000); + + rc = ogs_sbi_time_from_string(&t, "1987-01-01T12:00:27.87+0020"); + ABTS_INT_EQUAL(tc, 1, rc); + + ogs_gmtime(ogs_time_sec(t), &tm); + ABTS_INT_EQUAL(tc, 87, tm.tm_year); + ABTS_INT_EQUAL(tc, 0, tm.tm_mon); + ABTS_INT_EQUAL(tc, 1, tm.tm_mday); + ABTS_INT_EQUAL(tc, 11, tm.tm_hour); + ABTS_INT_EQUAL(tc, 40, tm.tm_min); + ABTS_INT_EQUAL(tc, 27, tm.tm_sec); + ABTS_INT_EQUAL(tc, 0, tm.tm_isdst); + ABTS_INT_EQUAL(tc, 0, tm.tm_gmtoff); + ABTS_TRUE(tc, t == 536499627870000); +} + +static void sbi_message_test5(abts_case *tc, void *data) +{ + char *str = NULL; + + str = ogs_sbi_timezone_string(-18000); + ABTS_STR_EQUAL(tc, "-05:00", str); + ogs_free(str); + + str = ogs_sbi_timezone_string(28800); + ABTS_STR_EQUAL(tc, "+08:00", str); + ogs_free(str); + + str = ogs_sbi_timezone_string(0); + ABTS_STR_EQUAL(tc, "+00:00", str); + ogs_free(str); +} + abts_suite *test_sbi_message(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -351,6 +491,8 @@ abts_suite *test_sbi_message(abts_suite *suite) abts_run_test(suite, sbi_message_test1, NULL); abts_run_test(suite, sbi_message_test2, NULL); abts_run_test(suite, sbi_message_test3, NULL); + abts_run_test(suite, sbi_message_test4, NULL); + abts_run_test(suite, sbi_message_test5, NULL); return suite; }