From d4b5291c623c546c57777191a47b6d9696a7e1cc Mon Sep 17 00:00:00 2001 From: Teodora Date: Wed, 27 Aug 2025 10:40:01 +0200 Subject: [PATCH] Facilitate RU notification initialization Use X macros for carriers and synchronization states, by mapping enum with the state values. --- radio/fhi_72/mplane/init-mplane.c | 64 +++++++++++++++----------- radio/fhi_72/mplane/ru-mplane-api.c | 14 ++++++ radio/fhi_72/mplane/ru-mplane-api.h | 34 ++++++++++++-- radio/fhi_72/mplane/subscribe-mplane.c | 28 ++--------- radio/fhi_72/oran_isolate.c | 2 +- 5 files changed, 88 insertions(+), 54 deletions(-) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index fc20ba5af4..f8a401b230 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -141,6 +141,31 @@ bool init_mplane(ru_session_list_t *ru_session_list) return true; } +static void init_ru_notif(ru_session_t *ru_session, const char* buffer) +{ + char* usage_state = get_ru_xml_node(buffer, "usage-state"); + if (usage_state != NULL && strcmp(usage_state, "busy") == 0) { + ru_session->ru_notif.rx_carrier_state = BUSY_CARRIER; + ru_session->ru_notif.tx_carrier_state = BUSY_CARRIER; + ru_session->ru_notif.config_change = true; + } else if (usage_state != NULL && strcmp(usage_state, "active") == 0) { + ru_session->ru_notif.rx_carrier_state = READY_CARRIER; + ru_session->ru_notif.tx_carrier_state = READY_CARRIER; + ru_session->ru_notif.config_change = true; + } else { // "idle" or NULL + ru_session->ru_notif.rx_carrier_state = DISABLED_CARRIER; + ru_session->ru_notif.tx_carrier_state = DISABLED_CARRIER; + ru_session->ru_notif.config_change = false; + } + + char *ptp_state = get_ru_xml_node(buffer, "sync-state"); + ru_session->ru_notif.ptp_state = str_to_enum_ptp(ptp_state); + MP_LOG_I("RU is in \"%s\" sync state.\n", ptp_state); + + free(usage_state); + free(ptp_state); +} + bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus) { bool success = false; @@ -149,12 +174,8 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz success = get_mplane(ru_session, &operational_ds); AssertError(success, return false, "[MPLANE] Unable to continue: could not get RU answer via get_mplane().\n"); - bool ptp_state = false; - const char *sync_state = get_ru_xml_node(operational_ds, "sync-state"); - if (strcmp(sync_state, "LOCKED") == 0) { - MP_LOG_I("RU is already PTP synchronized.\n"); - ptp_state = true; - } + // init RU notifications + init_ru_notif(ru_session, operational_ds); /* 1) as per M-plane spec, RU must be in supervised mode, where stream = NULL && filter = "/o-ran-supervision:supervision-notification"; @@ -163,7 +184,6 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz => since more than one subscription at the time within one session is not possible, we will subscribe to all notifications */ const char *stream = "NETCONF"; const char *filter = NULL; - ru_session->ru_notif.ptp_state = ptp_state; success = subscribe_mplane(ru_session, stream, filter, (void *)&ru_session->ru_notif); AssertError(success, return false, "[MPLANE] Unable to continue: could not get RU answer via subscribe_mplane().\n"); @@ -189,26 +209,18 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz success = load_yang_models(ru_session, operational_ds); AssertError(success, return false, "[MPLANE] Unable to load yang models.\n"); - if (ru_session->ru_notif.ptp_state) { - char *content = NULL; - success = configure_ru_from_yang(ru_session, oai, num_rus, &content); - AssertError(success, return false, "[MPLANE] Unable to create content for RPC for start-up procedure.\n"); + while (1) { + sleep(5); + if (!ru_session->ru_notif.ptp_state) { + char *content = NULL; + success = configure_ru_from_yang(ru_session, oai, num_rus, &content); + AssertError(success, return false, "[MPLANE] Unable to create content for RPC for start-up procedure.\n"); - success = edit_val_commmit_rpc(ru_session, content); - AssertError(success, return false, "[MPLANE] Unable to continue.\n"); - free(content); - } - - const char *usage_state = get_ru_xml_node(operational_ds, "usage-state"); - MP_LOG_I("Usage state = \"%s\" for RU \"%s\".\n", usage_state, ru_session->ru_ip_add); - if (strcmp(usage_state, "busy") == 0) { // carriers are already activated - ru_session->ru_notif.rx_carrier_state = true; - ru_session->ru_notif.tx_carrier_state = true; - ru_session->ru_notif.config_change = true; - } else { - ru_session->ru_notif.rx_carrier_state = false; - ru_session->ru_notif.tx_carrier_state = false; - ru_session->ru_notif.config_change = false; + success = edit_val_commmit_rpc(ru_session, content); + AssertError(success, return false, "[MPLANE] Unable to continue.\n"); + free(content); + break; + } } free(operational_ds); diff --git a/radio/fhi_72/mplane/ru-mplane-api.c b/radio/fhi_72/mplane/ru-mplane-api.c index df4bf3b8ba..acc3425ca1 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.c +++ b/radio/fhi_72/mplane/ru-mplane-api.c @@ -25,6 +25,20 @@ #include +ptp_state_e str_to_enum_ptp(const char* value) { +#define X(name, str) if (value != NULL && strcmp(value, str) == 0) return name; + PTP_STATE +#undef X + return PTP_COUNT; +}; + +carrier_state_e str_to_enum_carrier(const char* value) { +#define X(name, str) if (value != NULL && strcmp(value, str) == 0) return name; + CARRIER_STATE +#undef X + return CARRIER_COUNT; +}; + static void free_match_list(char **match_list, size_t count) { for (size_t i = 0; i < count; i++) { diff --git a/radio/fhi_72/mplane/ru-mplane-api.h b/radio/fhi_72/mplane/ru-mplane-api.h index 85fac5515c..46f4e27deb 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.h +++ b/radio/fhi_72/mplane/ru-mplane-api.h @@ -31,10 +31,38 @@ #define MP_LOG_I(x, args...) LOG_I(HW, "[MPLANE] " x, ##args) #define MP_LOG_W(x, args...) LOG_W(HW, "[MPLANE] " x, ##args) +#define PTP_STATE \ + X(LOCKED_PTP, "LOCKED") \ + X(FREERUN_PTP, "FREERUN") \ + X(HOLDOVER_PTP, "HOLDOVER") + +typedef enum { +#define X(name, str) name, + PTP_STATE +#undef X + PTP_COUNT +} ptp_state_e; + +ptp_state_e str_to_enum_ptp(const char* value); + +#define CARRIER_STATE \ + X(READY_CARRIER, "READY") \ + X(DISABLED_CARRIER, "DISABLED") \ + X(BUSY_CARRIER, "BUSY") + +typedef enum { +#define X(name, str) name, + CARRIER_STATE +#undef X + CARRIER_COUNT +} carrier_state_e; + +carrier_state_e str_to_enum_carrier(const char* value); + typedef struct { - bool ptp_state; - bool rx_carrier_state; - bool tx_carrier_state; + ptp_state_e ptp_state; // "LOCKED", "FREERUN", "HOLDOVER" + carrier_state_e rx_carrier_state; // "READY", "DISABLED", "BUSY" + carrier_state_e tx_carrier_state; // "READY", "DISABLED", "BUSY" bool config_change; // to be extended with any notification callback diff --git a/radio/fhi_72/mplane/subscribe-mplane.c b/radio/fhi_72/mplane/subscribe-mplane.c index bec7e28a68..bff81c5391 100644 --- a/radio/fhi_72/mplane/subscribe-mplane.c +++ b/radio/fhi_72/mplane/subscribe-mplane.c @@ -30,13 +30,8 @@ static void recv_notif_v1(const struct nc_notif *notif, ru_notif_t *answer) { const char *node_name = notif->tree->child->attr->name; - const char *value = notif->tree->child->attr->value_str; if (strcmp(node_name, "sync-state")) { - if (strcmp(value, "LOCKED") == 0) { - answer->ptp_state = true; - } else { - answer->ptp_state = false; - } + answer->ptp_state = str_to_enum_ptp(notif->tree->child->attr->value_str); } // carriers state - to be filled @@ -90,26 +85,11 @@ static void recv_notif_v2(struct lyd_node_inner *op, ru_notif_t *answer) const char *notif = op->schema->name; if (strcmp(notif, "synchronization-state-change") == 0) { - const char *value = lyd_get_value(op->child); - if (strcmp(value, "LOCKED") == 0) { - answer->ptp_state = true; - } else { // "FREERUN" or "HOLDOVER" - answer->ptp_state = false; - } + answer->ptp_state = str_to_enum_ptp(lyd_get_value(op->child)); } else if (strcmp(notif, "rx-array-carriers-state-change") == 0) { - const char *value = lyd_get_value(lyd_child(op->child)->next); - if (strcmp(value, "READY") == 0) { - answer->rx_carrier_state = true; - } else { // "DISABLED" or "BUSY" - answer->rx_carrier_state = false; - } + answer->rx_carrier_state = str_to_enum_carrier(lyd_get_value(lyd_child(op->child)->next)); } else if (strcmp(notif, "tx-array-carriers-state-change") == 0) { - const char *value = lyd_get_value(lyd_child(op->child)->next); - if (strcmp(value, "READY") == 0) { - answer->tx_carrier_state = true; - } else { // "DISABLED" or "BUSY" - answer->tx_carrier_state = false; - } + answer->tx_carrier_state = str_to_enum_carrier(lyd_get_value(lyd_child(op->child)->next)); } else if (strcmp(notif, "netconf-config-change") == 0) { answer->config_change = true; } diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 48e95e7344..8a2ac0ae46 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -342,7 +342,7 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d bool all_rus_ready = true; for (int i = 0; i < ru_session_list.num_rus; i++) { ru_session_t *ru_session = &ru_session_list.ru_session[i]; - if (!ru_ready[i] && ru_session->ru_notif.config_change && ru_session->ru_notif.rx_carrier_state && ru_session->ru_notif.tx_carrier_state) { + if (!ru_ready[i] && ru_session->ru_notif.config_change && !ru_session->ru_notif.rx_carrier_state && !ru_session->ru_notif.tx_carrier_state) { MP_LOG_I("RU \"%s\" is now ready.\n", ru_session->ru_ip_add); ru_ready[i] = true; if (!ru_session->pm_stats.start_up_timing) {