From 2583fd3c08435df123a662c40ddb4dc1914b50f2 Mon Sep 17 00:00:00 2001 From: jmasterfunk84 <48972964+jmasterfunk84@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:08:47 -0600 Subject: [PATCH] Introduce ability for multiple SDM_Subscriptions --- src/udm/context.c | 92 +++++++++++++++++++++++++++++++++++++++++- src/udm/context.h | 18 ++++++++- src/udm/nudm-handler.c | 39 ++++++++++++------ 3 files changed, 134 insertions(+), 15 deletions(-) diff --git a/src/udm/context.c b/src/udm/context.c index 4a2b73161..7f2079624 100644 --- a/src/udm/context.c +++ b/src/udm/context.c @@ -25,9 +25,12 @@ int __udm_log_domain; static OGS_POOL(udm_ue_pool, udm_ue_t); static OGS_POOL(udm_sess_pool, udm_sess_t); +static OGS_POOL(udm_sdm_subscription_pool, udm_sdm_subscription_t); static int context_initialized = 0; +static int max_num_of_udm_sdm_subscriptions = 0; + void udm_context_init(void) { ogs_assert(context_initialized == 0); @@ -39,6 +42,10 @@ void udm_context_init(void) ogs_pool_init(&udm_ue_pool, ogs_global_conf()->max.ue); ogs_pool_init(&udm_sess_pool, ogs_app()->pool.sess); +#define MAX_NUM_OF_UDM_SDM_SUBSCRIPTIONS_PER_UE 4 + max_num_of_udm_sdm_subscriptions = ogs_global_conf()->max.ue * + MAX_NUM_OF_UDM_SDM_SUBSCRIPTIONS_PER_UE; + ogs_pool_init(&udm_sdm_subscription_pool, max_num_of_udm_sdm_subscriptions); ogs_list_init(&self.udm_ue_list); self.suci_hash = ogs_hash_make(); @@ -46,6 +53,10 @@ void udm_context_init(void) self.supi_hash = ogs_hash_make(); ogs_assert(self.supi_hash); + ogs_list_init(&self.sdm_subscription_list); + self.sdm_subscription_id_hash = ogs_hash_make(); + ogs_assert(self.sdm_subscription_id_hash); + context_initialized = 1; } @@ -59,9 +70,12 @@ void udm_context_final(void) ogs_hash_destroy(self.suci_hash); ogs_assert(self.supi_hash); ogs_hash_destroy(self.supi_hash); + ogs_assert(self.sdm_subscription_id_hash); + ogs_hash_destroy(self.sdm_subscription_id_hash); ogs_pool_final(&udm_ue_pool); ogs_pool_final(&udm_sess_pool); + ogs_pool_final(&udm_sdm_subscription_pool); context_initialized = 0; } @@ -200,6 +214,7 @@ void udm_ue_remove(udm_ue_t *udm_ue) ogs_sbi_object_free(&udm_ue->sbi); udm_sess_remove_all(udm_ue); + udm_sdm_subscription_remove_all(udm_ue); OpenAPI_auth_event_free(udm_ue->auth_event); OpenAPI_amf3_gpp_access_registration_free( @@ -224,8 +239,6 @@ void udm_ue_remove(udm_ue_t *udm_ue) ogs_free(udm_ue->amf_instance_id); if (udm_ue->dereg_callback_uri) ogs_free(udm_ue->dereg_callback_uri); - if (udm_ue->data_change_callback_uri) - ogs_free(udm_ue->data_change_callback_uri); ogs_pool_free(&udm_ue_pool, udm_ue); } @@ -349,6 +362,81 @@ udm_sess_t *udm_sess_cycle(udm_sess_t *sess) return ogs_pool_cycle(&udm_sess_pool, sess); } +udm_sdm_subscription_t *udm_sdm_subscription_add(udm_ue_t *udm_ue) +{ + udm_sdm_subscription_t *sdm_subscription = NULL; + + char id[OGS_UUID_FORMATTED_LENGTH + 1]; + ogs_uuid_t uuid; + + ogs_assert(udm_ue); + + ogs_uuid_get(&uuid); + ogs_uuid_format(id, &uuid); + + ogs_pool_alloc(&udm_sdm_subscription_pool, &sdm_subscription); + if (!sdm_subscription) { + ogs_error("Maximum number of SDM Subscriptions [%d] reached", + max_num_of_udm_sdm_subscriptions); + return NULL; + } + memset(sdm_subscription, 0, sizeof *sdm_subscription); + + sdm_subscription->id = ogs_strdup(id); + if (!sdm_subscription->id) { + ogs_error("No memory for sdm_subscription->id [%s]", udm_ue->suci); + ogs_pool_free(&udm_sdm_subscription_pool, sdm_subscription); + return NULL; + } + + sdm_subscription->udm_ue = udm_ue; + + ogs_hash_set(self.sdm_subscription_id_hash, sdm_subscription->id, + strlen(sdm_subscription->id), sdm_subscription); + + ogs_list_add(&udm_ue->sdm_subscription_list, sdm_subscription); + + return sdm_subscription; +} + +void udm_sdm_subscription_remove(udm_sdm_subscription_t *sdm_subscription) +{ + ogs_assert(sdm_subscription); + ogs_assert(sdm_subscription->udm_ue); + + ogs_list_remove(&sdm_subscription->udm_ue->sdm_subscription_list, + sdm_subscription); + + ogs_assert(sdm_subscription->id); + ogs_hash_set(self.sdm_subscription_id_hash, sdm_subscription->id, + strlen(sdm_subscription->id), NULL); + ogs_free(sdm_subscription->id); + + if (sdm_subscription->data_change_callback_uri) + ogs_free(sdm_subscription->data_change_callback_uri); + + ogs_pool_free(&udm_sdm_subscription_pool, sdm_subscription); +} + +void udm_sdm_subscription_remove_all(udm_ue_t *udm_ue) +{ + udm_sdm_subscription_t *sdm_subscription = NULL, + *next_sdm_subscription = NULL; + + ogs_assert(udm_ue); + + ogs_list_for_each_safe(&udm_ue->sdm_subscription_list, + next_sdm_subscription, sdm_subscription) + udm_sdm_subscription_remove(sdm_subscription); +} + +udm_sdm_subscription_t *udm_sdm_subscription_find_by_id(char *id) +{ + ogs_assert(id); + return (udm_sdm_subscription_t *)ogs_hash_get(self.sdm_subscription_id_hash, + id, strlen(id)); +} + int get_ue_load(void) { return (((ogs_pool_size(&udm_ue_pool) - diff --git a/src/udm/context.h b/src/udm/context.h index 9a3cebdb8..791b5d1f2 100644 --- a/src/udm/context.h +++ b/src/udm/context.h @@ -37,8 +37,10 @@ extern int __udm_log_domain; typedef struct udm_context_s { ogs_list_t udm_ue_list; + ogs_list_t sdm_subscription_list; ogs_hash_t *suci_hash; ogs_hash_t *supi_hash; + ogs_hash_t *sdm_subscription_id_hash; } udm_context_t; @@ -58,7 +60,6 @@ struct udm_ue_s { char *amf_instance_id; char *dereg_callback_uri; - char *data_change_callback_uri; uint8_t k[OGS_KEY_LEN]; uint8_t opc[OGS_KEY_LEN]; @@ -72,6 +73,7 @@ struct udm_ue_s { OpenAPI_rat_type_e rat_type; ogs_list_t sess_list; + ogs_list_t sdm_subscription_list; }; struct udm_sess_s { @@ -88,6 +90,15 @@ struct udm_sess_s { udm_ue_t *udm_ue; }; +typedef struct udm_sdm_subscription_s { + ogs_lnode_t lnode; + + char *id; + char *data_change_callback_uri; + + udm_ue_t *udm_ue; +} udm_sdm_subscription_t; + void udm_context_init(void); void udm_context_final(void); udm_context_t *udm_self(void); @@ -110,6 +121,11 @@ udm_sess_t *udm_sess_find_by_psi(udm_ue_t *udm_ue, uint8_t psi); udm_ue_t *udm_ue_cycle(udm_ue_t *udm_ue); udm_sess_t *udm_sess_cycle(udm_sess_t *sess); +udm_sdm_subscription_t *udm_sdm_subscription_add(udm_ue_t *udm_ue); +void udm_sdm_subscription_remove(udm_sdm_subscription_t *subscription); +void udm_sdm_subscription_remove_all(udm_ue_t *udm_ue); +udm_sdm_subscription_t *udm_sdm_subscription_find_by_id(char *id); + int get_ue_load(void); #ifdef __cplusplus diff --git a/src/udm/nudm-handler.c b/src/udm/nudm-handler.c index 8ac826858..63b180db8 100644 --- a/src/udm/nudm-handler.c +++ b/src/udm/nudm-handler.c @@ -601,6 +601,8 @@ bool udm_nudm_sdm_handle_subscription_create( OpenAPI_sdm_subscription_t *SDMSubscription = NULL; + udm_sdm_subscription_t *sdm_subscription = NULL; + ogs_assert(udm_ue); ogs_assert(stream); ogs_assert(recvmsg); @@ -639,11 +641,11 @@ bool udm_nudm_sdm_handle_subscription_create( return false; } - if (udm_ue->data_change_callback_uri) - ogs_free(udm_ue->data_change_callback_uri); - udm_ue->data_change_callback_uri = - ogs_strdup(SDMSubscription->callback_reference); + sdm_subscription = udm_sdm_subscription_add(udm_ue); + ogs_assert(sdm_subscription); + sdm_subscription->data_change_callback_uri = + ogs_strdup(SDMSubscription->callback_reference); server = ogs_sbi_server_from_stream(stream); ogs_assert(server); @@ -654,8 +656,7 @@ bool udm_nudm_sdm_handle_subscription_create( header.resource.component[0] = udm_ue->supi; header.resource.component[1] = (char *)OGS_SBI_RESOURCE_NAME_SDM_SUBSCRIPTIONS; - /* TODO: subscription id */ - header.resource.component[2] = udm_ue->ctx_id; + header.resource.component[2] = sdm_subscription->id; memset(&sendmsg, 0, sizeof(sendmsg)); sendmsg.http.location = ogs_sbi_server_uri(server, &header); @@ -678,19 +679,33 @@ bool udm_nudm_sdm_handle_subscription_delete( { ogs_sbi_message_t sendmsg; ogs_sbi_response_t *response = NULL; - ogs_sbi_server_t *server = NULL; + udm_sdm_subscription_t *sdm_subscription; ogs_assert(udm_ue); ogs_assert(stream); ogs_assert(recvmsg); - if (udm_ue->data_change_callback_uri) { - ogs_free(udm_ue->data_change_callback_uri); - udm_ue->data_change_callback_uri = NULL; + if (!recvmsg->h.resource.component[2]) { + ogs_error("[%s] No subscriptionID", udm_ue->supi); + ogs_assert(true == + ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, + recvmsg, "No subscriptionID", udm_ue->supi)); + return false; } + sdm_subscription = udm_sdm_subscription_find_by_id( + recvmsg->h.resource.component[2]); - server = ogs_sbi_server_from_stream(stream); - ogs_assert(server); + if (sdm_subscription) { + udm_sdm_subscription_remove(sdm_subscription); + } else { + ogs_error("Subscription to be deleted does not exist [%s]", + recvmsg->h.resource.component[2]); + ogs_assert(true == + ogs_sbi_server_send_error( + stream, OGS_SBI_HTTP_STATUS_NOT_FOUND, + recvmsg, "Subscription Not found", recvmsg->h.method)); + return false; + } memset(&sendmsg, 0, sizeof(sendmsg)); response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);