diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index 0092f96698..f028be8102 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -30,6 +30,7 @@ target_sources(oran_fhlib_5g_mplane PRIVATE rpc-send-recv.c get-mplane.c subscribe-mplane.c + ru-mplane-api.c xml/get-xml.c ) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index 453a8b1390..34d68a30d0 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -165,6 +165,11 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz AssertError(success, return false, "[MPLANE] Unable to update the watchdog timer. RU will do a reset after default supervision timer of (60+10)[s] expires.\n"); MP_LOG_I("Watchdog timer answer: \n\t%s\n", watchdog_answer); + // save RU info for xran + const int max_num_ant = max(oai->tx_num_channels/num_rus, oai->rx_num_channels/num_rus); + success = get_config_for_xran(operational_ds, max_num_ant, &ru_session->xran_mplane); + AssertError(success, return false, "[MPLANE] Unable to retrieve required info for xran from RU \"%s\".\n", ru_session->ru_ip_add); + free(operational_ds); free(watchdog_answer); diff --git a/radio/fhi_72/mplane/ru-mplane-api.c b/radio/fhi_72/mplane/ru-mplane-api.c new file mode 100644 index 0000000000..ada42fd841 --- /dev/null +++ b/radio/fhi_72/mplane/ru-mplane-api.c @@ -0,0 +1,127 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "ru-mplane-api.h" +#include "xml/get-xml.h" +#include "common/utils/assertions.h" + +#include + +static void free_match_list(char **match_list, size_t count) +{ + for (size_t i = 0; i < count; i++) { + free(match_list[i]); + } + free(match_list); +} + +static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t interface_mtu, const int16_t first_iq_width, const int max_num_ant) +{ + if (interface_mtu == 1500) { + MP_LOG_I("Interface MTU %d unreliable/not correctly reported by Benetel O-RU, hardcoding to 9600.\n", interface_mtu); + xran_mplane->mtu = 9600; + } else { + xran_mplane->mtu = interface_mtu; + } + + if (first_iq_width != 9) { + MP_LOG_I("IQ bitwidth %d unreliable/not correctly reported by Benetel O-RU, hardcoding to 9.\n", first_iq_width); + xran_mplane->iq_width = 9; + } else { + xran_mplane->iq_width = first_iq_width; + } + + xran_mplane->prach_offset = max_num_ant; +} + +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"); + + // 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, "interface-mtu")); + + // IQ bitwidth + char **match_list = NULL; + size_t count = 0; + get_ru_xml_list(buffer, "iq-bitwidth", &match_list, &count); + const int16_t first_iq_width = (int16_t)atoi((char *)match_list[0]); + free_match_list(match_list, count); + + // PRACH offset + // xran_mplane->prach_offset + + // DU port ID bitmask + xran_mplane->du_port_bitmask = 0xf000; + // Band sector bitmask + xran_mplane->band_sector_bitmask = 0x0f00; + // CC ID bitmask + xran_mplane->ccid_bitmask = 0x00f0; + // RU port ID bitmask + xran_mplane->ru_port_bitmask = 0x000f; + + // DU port ID + xran_mplane->du_port = 0; + // Band sector + xran_mplane->band_sector = 0; + // CC ID + xran_mplane->ccid = 0; + // RU port ID + xran_mplane->ru_port = 0; + + 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); + } else { + AssertError(false, return false, "[MPLANE] %s RU currently not supported.\n", ru_vendor); + } + + MP_LOG_I("Storing the following information to forward to xran:\n\ + RU MAC address %s\n\ + MTU %d\n\ + IQ bitwidth %d\n\ + PRACH offset %d\n\ + DU port bitmask %d\n\ + Band sector bitmask %d\n\ + CC ID bitmask %d\n\ + RU port ID bitmask %d\n\ + DU port ID %d\n\ + Band sector ID %d\n\ + CC ID %d\n\ + RU port ID %d\n", + xran_mplane->ru_mac_addr, + xran_mplane->mtu, + xran_mplane->iq_width, + xran_mplane->prach_offset, + xran_mplane->du_port_bitmask, + xran_mplane->band_sector_bitmask, + xran_mplane->ccid_bitmask, + xran_mplane->ru_port_bitmask, + xran_mplane->du_port, + xran_mplane->band_sector, + xran_mplane->ccid, + xran_mplane->ru_port); + + return true; +} diff --git a/radio/fhi_72/mplane/ru-mplane-api.h b/radio/fhi_72/mplane/ru-mplane-api.h index 4b3b1719c1..5b49814efa 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.h +++ b/radio/fhi_72/mplane/ru-mplane-api.h @@ -92,4 +92,6 @@ typedef struct { } ru_session_list_t; +bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_t *xran_mplane); + #endif /* RU_MPLANE_API_H */