diff --git a/radio/fhi_72/mplane/connect-mplane.c b/radio/fhi_72/mplane/connect-mplane.c index 9744ce01e8..9d00d26bdf 100644 --- a/radio/fhi_72/mplane/connect-mplane.c +++ b/radio/fhi_72/mplane/connect-mplane.c @@ -59,24 +59,7 @@ bool connect_mplane(ru_session_t *ru_session) void disconnect_mplane(void *rus_disconnect) { ru_session_list_t *ru_session_list = (ru_session_list_t *)rus_disconnect; - - for (size_t i = 0; i num_rus; i++) { - ru_session_t *ru_session = &ru_session_list->ru_session[i]; - if (ru_session->session == NULL) - continue; - MP_LOG_I("Sending PM de-activation request for RU \"%s\".\n", ru_session->ru_ip_add); - bool success = pm_conf(ru_session, "false"); - if (success) - MP_LOG_I("Successfully de-activated PM for RU \"%s\".\n", ru_session->ru_ip_add); - MP_LOG_I("Disconnecting from RU \"%s\".\n", ru_session->ru_ip_add); - nc_session_free(ru_session->session, NULL); - ru_session->session = NULL; -#ifdef MPLANE_V1 - ly_ctx_destroy((struct ly_ctx *)ru_session->ctx, NULL); -#elif defined MPLANE_V2 - ly_ctx_destroy((struct ly_ctx *)ru_session->ctx); -#endif - } + free_ru_session_list(ru_session_list); nc_client_destroy(); } diff --git a/radio/fhi_72/mplane/ru-mplane-api.c b/radio/fhi_72/mplane/ru-mplane-api.c index 649cf34a20..f04e294dfc 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.c +++ b/radio/fhi_72/mplane/ru-mplane-api.c @@ -20,11 +20,110 @@ */ #include "ru-mplane-api.h" +#include "init-mplane.h" #include "xml/get-xml.h" #include "common/utils/assertions.h" #include +#include +#include + +static void free_pm_stats(pm_stats_t *src) +{ + // free Rx window measurements + for (size_t i = 0; i < src->rx_num; i++) { + free(src->rx_window_meas[i]); + } + free(src->rx_window_meas); + + // free Tx measurements + for (size_t i = 0; i < src->tx_num; i++) { + free(src->tx_meas[i]); + } + free(src->tx_meas); +} + +static void free_uplane_info(uplane_info_t *src) +{ + for (size_t i = 0; i < src->num; i++) { + free(src->name[i]); + } + free(src->name); +} + +static void free_ru_mplane_config(ru_mplane_config_t *src) +{ + // free DU MAC address(es) and VLAN tag(s) + for (size_t i = 0; i < src->num_cu_planes; i++) { + free(src->du_mac_addr[i]); + } + free(src->du_mac_addr); + free(src->vlan_tag); + + // free interface name + free(src->interface_name); + + // free endpoints and carriers + free_uplane_info(&src->tx_endpoints); + free_uplane_info(&src->rx_endpoints); + free_uplane_info(&src->tx_carriers); + free_uplane_info(&src->rx_carriers); +} + +static void free_ru_session(ru_session_t *src) +{ + // username + free(src->username); + + // if no RU connected to, free only the initialized RU IP address + if (src->session == NULL) { + free(src->ru_ip_add); + return; + } + + // disconnect from the RU + MP_LOG_I("Sending PM de-activation request for RU \"%s\".\n", src->ru_ip_add); + bool success = pm_conf(src, "false"); + if (success) + MP_LOG_I("Successfully de-activated PM for RU \"%s\".\n", src->ru_ip_add); + MP_LOG_I("Disconnecting from RU \"%s\".\n", src->ru_ip_add); + + // free RU IP address + free(src->ru_ip_add); + // free RU M-plane config + free_ru_mplane_config(&src->ru_mplane_config); + // free NETCONF session + nc_session_free(src->session, NULL); + src->session = NULL; + // free libyang context +#ifdef MPLANE_V1 + ly_ctx_destroy((struct ly_ctx *)src->ctx, NULL); +#elif defined MPLANE_V2 + ly_ctx_destroy((struct ly_ctx *)src->ctx); +#endif + // free only the RU MAC addressin xran M-plane info + free(src->xran_mplane.ru_mac_addr); + // nothing to free in ru_notif + // free PM stats + free_pm_stats(&src->pm_stats); +} + +void free_ru_session_list(ru_session_list_t *src) +{ + // DU key pair + for (size_t i = 0; i < 2; i++) { + free(src->du_key_pair[i]); + } + free(src->du_key_pair); + + // RU session + for (size_t i = 0; i < src->num_rus; i++) { + free_ru_session(&src->ru_session[i]); + } + free(src->ru_session); +} + oper_state_e str_to_enum_oper(const char* value) { #define X(name, str) if (value != NULL && strcmp(value, str) == 0) return name; OPER_STATE @@ -98,13 +197,15 @@ static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t inter bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_t *xran_mplane) { /* some O-RU vendors are not fully compliant as per M-plane specifications */ - const char *ru_vendor = get_ru_xml_node(buffer, "mfg-name"); + char *ru_vendor = get_ru_xml_node(buffer, "mfg-name"); // RU MAC xran_mplane->ru_mac_addr = get_ru_xml_node(buffer, "mac-address"); // TODO: support for VVDN, as it defines multiple MAC addresses // MTU - const uint32_t interface_mtu = (uint32_t)atoi(get_ru_xml_node(buffer, "l2-mtu")); + char *int_mtu_str = get_ru_xml_node(buffer, "l2-mtu"); + const uint32_t interface_mtu = (uint32_t)atoi(int_mtu_str); + free(int_mtu_str); // IQ bitwidth char **match_list = NULL; @@ -142,14 +243,17 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ free_match_list(match_list, count); // Managed delay support - const char *managed_delay = get_ru_xml_node(buffer, "managed-delay-support"); + char *managed_delay = get_ru_xml_node(buffer, "managed-delay-support"); xran_mplane->managed_delay = (strcasecmp(managed_delay, "NON_MANAGED") == 0) ? false : true; + free(managed_delay); // Store the max gain - xran_mplane->max_tx_gain = (double)atof(get_ru_xml_node(buffer, "max-gain")); + char *max_tx_gain_str = get_ru_xml_node(buffer, "max-gain"); + xran_mplane->max_tx_gain = (double)atof(max_tx_gain_str); + free(max_tx_gain_str); // Model name - const char *model_name = get_ru_xml_node(buffer, "model-name"); + char *model_name = get_ru_xml_node(buffer, "model-name"); if (strcasecmp(ru_vendor, "BENETEL") == 0 /* || strcmp(ru_vendor, "VVDN-LPRU") == 0 || strcmp(ru_vendor, "Metanoia") == 0 */) { fix_benetel_setting(xran_mplane, interface_mtu, first_iq_width, max_num_ant, model_name); @@ -185,6 +289,9 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ xran_mplane->ru_port, xran_mplane->max_tx_gain); + free(ru_vendor); + free(model_name); + return true; } @@ -220,7 +327,7 @@ bool get_uplane_info(const char *buffer, ru_mplane_config_t *ru_mplane_config) bool get_pm_object_list(const char *buffer, pm_stats_t *pm_stats) { - const char *ru_vendor = get_ru_xml_node(buffer, "mfg-name"); + char *ru_vendor = get_ru_xml_node(buffer, "mfg-name"); if (strcasecmp(ru_vendor, "BENETEL") == 0) { pm_stats->start_up_timing = false; } else { @@ -235,5 +342,7 @@ bool get_pm_object_list(const char *buffer, pm_stats_t *pm_stats) MP_LOG_I("Successfully retreived all performance measurement names.\n"); + free(ru_vendor); + return true; } diff --git a/radio/fhi_72/mplane/ru-mplane-api.h b/radio/fhi_72/mplane/ru-mplane-api.h index f221f7117c..f568bbaf3e 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.h +++ b/radio/fhi_72/mplane/ru-mplane-api.h @@ -188,6 +188,8 @@ typedef struct { } ru_session_list_t; +void free_ru_session_list(ru_session_list_t *src); + bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_t *xran_mplane); bool get_uplane_info(const char *buffer, ru_mplane_config_t *ru_mplane_config); diff --git a/radio/fhi_72/mplane/subscribe-mplane.c b/radio/fhi_72/mplane/subscribe-mplane.c index ffb77265e5..38c770848d 100644 --- a/radio/fhi_72/mplane/subscribe-mplane.c +++ b/radio/fhi_72/mplane/subscribe-mplane.c @@ -47,6 +47,8 @@ static void notif_clb_v1(struct nc_session *session, const struct nc_notif *noti MP_LOG_I("\nReceived notification at (%s)\n%s\n", notif->datetime, subs_reply); recv_notif_v1(notif, answer); + + free(subs_reply); } #elif MPLANE_V2 static void log_v2_pm_info(const char *ru_ip_add, struct lyd_node_inner *stats) @@ -124,11 +126,14 @@ static void notif_clb_v2(struct nc_session *session, const struct lyd_node *envp struct lyd_node_inner *op_inner = (struct lyd_node_inner *)op; if (strcmp(op_inner->schema->name, "measurement-result-stats") == 0) { log_v2_pm_info(ru_ip_add, op_inner); + free(subs_reply); return; } MP_LOG_I("Received notification from RU \"%s\" at (%s)\n%s\n", ru_ip_add, ((struct lyd_node_opaq *)lyd_child(envp))->value, subs_reply); recv_notif_v2(op_inner, answer); + + free(subs_reply); } #endif diff --git a/radio/fhi_72/mplane/xml/get-xml.c b/radio/fhi_72/mplane/xml/get-xml.c index 8ebd783901..138896103f 100644 --- a/radio/fhi_72/mplane/xml/get-xml.c +++ b/radio/fhi_72/mplane/xml/get-xml.c @@ -25,7 +25,7 @@ #include #include -static char *find_ru_xml_node(xmlNode *node, const char *filter) +static xmlChar *find_ru_xml_node(xmlNode *node, const char *filter) { for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next) { if (cur_node->type != XML_ELEMENT_NODE) @@ -40,9 +40,9 @@ static char *find_ru_xml_node(xmlNode *node, const char *filter) break; } } - return (char *)xmlNodeGetContent(target_node); + return xmlNodeGetContent(target_node); } - char *answer = find_ru_xml_node(cur_node->children, filter); + xmlChar *answer = find_ru_xml_node(cur_node->children, filter); if (answer != NULL) { return answer; } @@ -57,7 +57,13 @@ char *get_ru_xml_node(const char *buffer, const char *filter) xmlDoc *doc = xmlReadMemory(buffer, len, NULL, NULL, 0); xmlNode *root_element = xmlDocGetRootElement(doc); - return find_ru_xml_node(root_element->children, filter); + xmlChar *content = find_ru_xml_node(root_element->children, filter); + + char *value = strdup((char *)content); + xmlFree(content); + xmlFreeDoc(doc); + + return value; } static void find_ru_xml_list(xmlNode *node, const char *filter, char ***match_list, size_t *count) @@ -75,11 +81,12 @@ static void find_ru_xml_list(xmlNode *node, const char *filter, char ***match_li break; } } - const char *content = (const char *)xmlNodeGetContent(name_node ? name_node : cur_node); + xmlChar *content = xmlNodeGetContent(name_node ? name_node : cur_node); if (content) { *match_list = realloc(*match_list, (*count + 1) * sizeof(char *)); - (*match_list)[*count] = strdup(content); + (*match_list)[*count] = strdup((char *)content); (*count)++; + xmlFree(content); } } find_ru_xml_list(cur_node->children, filter, match_list, count); @@ -94,4 +101,6 @@ void get_ru_xml_list(const char *buffer, const char *filter, char ***match_list, xmlNode *root_element = xmlDocGetRootElement(doc); find_ru_xml_list(root_element->children, filter, match_list, count); + + xmlFreeDoc(doc); } diff --git a/radio/fhi_72/mplane/yang/get-yang.c b/radio/fhi_72/mplane/yang/get-yang.c index 08abeb4896..2eb39aa1d6 100644 --- a/radio/fhi_72/mplane/yang/get-yang.c +++ b/radio/fhi_72/mplane/yang/get-yang.c @@ -42,20 +42,30 @@ static bool store_schemas(xmlNode *node, ru_session_t *ru_session, struct ly_ctx if (strcmp((const char *)cur_node->name, "schema") == 0) { xmlNode *name_node = xmlFirstElementChild(cur_node); - char *module_name = (char *)xmlNodeGetContent(name_node); + xmlChar *module_name = xmlNodeGetContent(name_node); xmlNode *revision_node = xmlNextElementSibling(name_node); - char *module_revision = (char *)xmlNodeGetContent(revision_node); + xmlChar *module_revision = xmlNodeGetContent(revision_node); xmlNode *format_node = xmlNextElementSibling(revision_node); - char *module_format = (char *)xmlNodeGetContent(format_node); + xmlChar *module_format = xmlNodeGetContent(format_node); - if (strcmp(module_format, "yang") != 0) + if (strcmp((char*)module_format, "yang") != 0) { + xmlFree(module_name); + xmlFree(module_revision); + xmlFree(module_format); continue; + } MP_LOG_I("RPC request to RU \"%s\" = for module \"%s\".\n", ru_session->ru_ip_add, module_name); - struct nc_rpc *get_schema_rpc = nc_rpc_getschema(module_name, module_revision, "yang", param); + struct nc_rpc *get_schema_rpc = nc_rpc_getschema((char*)module_name, (char*)module_revision, "yang", param); char *schema_data = NULL; bool success = rpc_send_recv((struct nc_session *)ru_session->session, get_schema_rpc, wd, timeout, &schema_data); - AssertError(success, return false, "[MPLANE] Unable to get schema for module \"%s\" from RU \"%s\".\n", module_name, ru_session->ru_ip_add); + if (!success) { + MP_LOG_W("[MPLANE] Unable to get schema for module \"%s\" from RU \"%s\".\n", module_name, ru_session->ru_ip_add); + xmlFree(module_name); + xmlFree(module_revision); + xmlFree(module_format); + return false; + } if (schema_data) { #ifdef MPLANE_V1 @@ -73,10 +83,16 @@ static bool store_schemas(xmlNode *node, ru_session_t *ru_session, struct ly_ctx #elif defined MPLANE_V2 ly_ctx_destroy(*ctx); #endif - return false; - } + xmlFree(module_name); + xmlFree(module_revision); + xmlFree(module_format); + return false; + } } nc_rpc_free(get_schema_rpc); + xmlFree(module_name); + xmlFree(module_revision); + xmlFree(module_format); } } @@ -109,6 +125,7 @@ bool load_yang_models(ru_session_t *ru_session, const char *buffer) xmlNode *root_element = xmlDocGetRootElement(doc); bool success = load_from_operational_ds(root_element->children, ru_session, ctx); + xmlFreeDoc(doc); if (success) { MP_LOG_I("Successfully loaded all yang modules from operational datastore for RU \"%s\".\n", ru_session->ru_ip_add); return true;