From 3a095ac57edd930818cbca109d783b9eb0a99748 Mon Sep 17 00:00:00 2001 From: Teodora Date: Wed, 11 Dec 2024 14:14:34 +0100 Subject: [PATCH 01/27] M-plane support - explanation on needed parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RU IP address - to connect to RUs via netconf - DU MAC address - for setting up the CU-planes on RU; not used in xran - VLAN tag (*) - for setting up the CU-planes on RU; not used in xran - DU keypair - for authentication when connecting to RU(s) The parameters that RU-controller shall retreive from RU list of capabilities: - MTU - compression - RU MAC address - PRACH offset (**) (*) VLAN tag is not used in xran but an option is given in fh_config struct. In my opinion, it is not a very suitable place, as it is needed for VFs. Therefore, I moved it in the initialization part for M-plane purposes. (**) PRACH offset shall be >= max(Ntx,Nrx), as per O-RAN CUS specification: "The O-DU may decide to use same eAxC ID value to address endpoints on different O-RUs, but eAxC ID values assigned to one O-RU must be unique within the O-RU’s endpoints of same direction." => however, LITEON supports flexible assignment of PRACH eAxC IDs, so we made a workaround in the xran library to support PRACH eAxC IDs same as PUSCH eAxC IDs. --- radio/fhi_72/oran-config.c | 4 ++-- radio/fhi_72/oran-params.h | 26 +++++++++++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index 2f2032c30a..ba8fb2fcea 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -839,8 +839,8 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat, #endif fh_config->puschMaskEnable = 0; // enable PUSCH mask; only used if id = O_RU fh_config->puschMaskSlot = 0; // specific which slot PUSCH channel masked; only used if id = O_RU - fh_config->cp_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_CP_VLAN_TAG)->uptr; // C-plane VLAN tag; not used in xran; needed for M-plane - fh_config->up_vlan_tag = *gpd(fhp, nfh, ORAN_FH_CONFIG_UP_VLAN_TAG)->uptr; // U-plane VLAN tag; not used in xran; needed for M-plane + fh_config->cp_vlan_tag = 0; // C-plane VLAN tag; not used in xran; needed for M-plane + fh_config->up_vlan_tag = 0; // U-plane VLAN tag; not used in xran; needed for M-plane fh_config->debugStop = 0; // enable auto stop; only used if id = O_RU fh_config->debugStopCount = 0; // enable auto stop after number of Tx packets; not used in xran fh_config->DynamicSectionEna = 0; // enable dynamic C-Plane section allocation diff --git a/radio/fhi_72/oran-params.h b/radio/fhi_72/oran-params.h index 20c3d71634..42aabd99bb 100644 --- a/radio/fhi_72/oran-params.h +++ b/radio/fhi_72/oran-params.h @@ -31,8 +31,12 @@ #define ORAN_CONFIG_SYSTEM_CORE "system_core" #define ORAN_CONFIG_IO_CORE "io_core" #define ORAN_CONFIG_WORKER_CORES "worker_cores" -#define ORAN_CONFIG_RU_ADDR "ru_addr" -#define ORAN_CONFIG_MTU "mtu" +#define ORAN_CONFIG_DU_KEYPAIR "du_key_pair" // only needed for M-plane +#define ORAN_CONFIG_DU_ADDR "du_addr" // only needed for M-plane +#define ORAN_CONFIG_VLAN_TAG "vlan_tag" // only needed for M-plane +#define ORAN_CONFIG_RU_ADDR "ru_addr" // not needed if M-plane used +#define ORAN_CONFIG_RU_IP_ADDR "ru_ip_addr" // only needed for M-plane +#define ORAN_CONFIG_MTU "mtu" // not needed if M-plane used #define ORAN_CONFIG_FILE_PREFIX "file_prefix" #define ORAN_CONFIG_NETHPERPORT "eth_lines" #define ORAN_CONFIG_NETHSPEED "eth_speed" @@ -48,7 +52,11 @@ {ORAN_CONFIG_SYSTEM_CORE, "DPDK control threads core\n", PARAMFLAG_MANDATORY, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {ORAN_CONFIG_IO_CORE, "DPDK Core used for IO\n", PARAMFLAG_MANDATORY, .iptr=NULL, .defintval=4, TYPE_INT, 0}, \ {ORAN_CONFIG_WORKER_CORES, "CPU Cores to use for workers\n", PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=NULL,TYPE_UINTARRAY, 0}, \ + {ORAN_CONFIG_DU_KEYPAIR, "DU keypair for RU authentication\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ + {ORAN_CONFIG_DU_ADDR, "Ether addr of DU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ + {ORAN_CONFIG_VLAN_TAG, "VLAN tag\n", PARAMFLAG_MANDATORY, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ {ORAN_CONFIG_RU_ADDR, "Ether addr of RU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ + {ORAN_CONFIG_RU_IP_ADDR, "IP addr of RU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ {ORAN_CONFIG_MTU, "MTU of Eth interface\n", 0, .uptr=NULL, .defuintval=1500, TYPE_UINT, 0}, \ {ORAN_CONFIG_FILE_PREFIX, "DPDK file-prefix\n", 0, .strptr=NULL, .defstrval="wls_0", TYPE_STRING, 0}, \ {ORAN_CONFIG_NETHPERPORT, "number of links per port\n", 0, .uptr=NULL, .defuintval=1, TYPE_UINT, 0}, \ @@ -70,6 +78,10 @@ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ { .s3a = { config_checkstr_assign_integer, \ {"PA", "VA"}, {0, 1}, 2} }, \ { .s5 = { NULL } }, \ @@ -84,8 +96,6 @@ #define ORAN_FH_CONFIG_T1A_CP_UL "T1a_cp_ul" #define ORAN_FH_CONFIG_T1A_UP "T1a_up" #define ORAN_FH_CONFIG_TA4 "Ta4" -#define ORAN_FH_CONFIG_CP_VLAN_TAG "cp_vlan_tag" -#define ORAN_FH_CONFIG_UP_VLAN_TAG "up_vlan_tag" #define ORAN_FH_HLP_CPLT " parameter of RU in list form (Min&Max, length 2!)\n" @@ -95,15 +105,13 @@ {ORAN_FH_CONFIG_T1A_CP_UL, "T1a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ {ORAN_FH_CONFIG_T1A_UP, "T1a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ {ORAN_FH_CONFIG_TA4, "Ta4" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ - {ORAN_FH_CONFIG_CP_VLAN_TAG, "not used by xran", 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ - {ORAN_FH_CONFIG_UP_VLAN_TAG, "not used by xran", 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ } // clang-format on #define CONFIG_STRING_ORAN_RU "ru_config" -#define ORAN_RU_CONFIG_IQWIDTH "iq_width" -#define ORAN_RU_CONFIG_IQWIDTH_PRACH "iq_width_prach" +#define ORAN_RU_CONFIG_IQWIDTH "iq_width" // not needed if M-plane used +#define ORAN_RU_CONFIG_IQWIDTH_PRACH "iq_width_prach" // not needed if M-plane used // clang-format off #define ORAN_RU_DESC {\ @@ -114,7 +122,7 @@ #define CONFIG_STRING_ORAN_PRACH "prach_config" -#define ORAN_PRACH_CONFIG_EAXC_OFFSET "eAxC_offset" +#define ORAN_PRACH_CONFIG_EAXC_OFFSET "eAxC_offset" // not needed if M-plane used #define ORAN_PRACH_CONFIG_KBAR "kbar" // clang-format off From 3219d0a5a1215de986eac283e43c41ab47b5f0eb Mon Sep 17 00:00:00 2001 From: Teodora Date: Wed, 11 Dec 2024 23:19:46 +0100 Subject: [PATCH 02/27] Delete duplicated FindLibXml2.cmake file - cmake version 3.12 defines libxml2 module; the default path is /usr/share/cmake-3./Modules/FindLibXml2.cmake - OAI requires minimum cmake version 3.16 --- cmake_targets/tools/MODULES/FindLibXml2.cmake | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100755 cmake_targets/tools/MODULES/FindLibXml2.cmake diff --git a/cmake_targets/tools/MODULES/FindLibXml2.cmake b/cmake_targets/tools/MODULES/FindLibXml2.cmake deleted file mode 100755 index e18dc2e921..0000000000 --- a/cmake_targets/tools/MODULES/FindLibXml2.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# - Try to find the LibXml2 xml processing library -# Once done this will define -# -# LIBXML2_FOUND - System has LibXml2 -# LIBXML2_INCLUDE_DIR - The LibXml2 include directory -# LIBXML2_LIBRARIES - The libraries needed to use LibXml2 -# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2 -# LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2 - -#============================================================================= -# Copyright 2006-2009 Kitware, Inc. -# Copyright 2006 Alexander Neundorf -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - -# use pkg-config to get the directories and then use these values -# in the FIND_PATH() and FIND_LIBRARY() calls -FIND_PACKAGE(PkgConfig) -PKG_CHECK_MODULES(PC_LIBXML libxml-2.0) -SET(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER}) - -FIND_PATH(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h - HINTS - ${PC_LIBXML_INCLUDEDIR} - ${PC_LIBXML_INCLUDE_DIRS} - PATH_SUFFIXES libxml2 - ) - -FIND_LIBRARY(LIBXML2_LIBRARIES NAMES xml2 libxml2 - HINTS - ${PC_LIBXML_LIBDIR} - ${PC_LIBXML_LIBRARY_DIRS} - ) - -FIND_PROGRAM(LIBXML2_XMLLINT_EXECUTABLE xmllint) -# for backwards compat. with KDE 4.0.x: -SET(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}") - -# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) - -MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE) - From 978fa2ed053d7353932a7e3e56f5ccc282f7c399 Mon Sep 17 00:00:00 2001 From: Teodora Date: Sat, 15 Feb 2025 17:04:43 +0100 Subject: [PATCH 03/27] These commands are unnecessary - the FHI72 CMakeLists.txt exists and POST_BUILD properly links oran_fhlib_5g library --- cmake_targets/build_oai | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 27bb63ff89..d92e488e90 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -504,12 +504,6 @@ function main() { echo_info "Built Doxygen based documentation. The documentation file is located here: $DIR/$BUILD_DIR/build/doc/html/index.html" fi - # TODO: once we got the CMakeLists.txt file done for the ORAN files, remove the following lines - if [[ $TARGET_LIST =~ "oran_fhlib_5g" ]]; then - rm -f liboai_transpro.so - ln -s liboran_fhlib_5g.so liboai_transpro.so - fi - if [ "$UE" = 1 ] ; then echo_info "Compiling UE specific part" From efcc9fc9d4f66e19f4e1da1667acfcca905350c2 Mon Sep 17 00:00:00 2001 From: Teodora Date: Sat, 15 Feb 2025 17:13:30 +0100 Subject: [PATCH 04/27] Properly include xran_common.h in ${xran_INCLUDE_DIRS} - ${xran_LOCATION}/src/xran_common.h - delete unnecessary target_include_directories() from FHI72 --- cmake_targets/tools/MODULES/Findxran.cmake | 10 ++++++---- radio/fhi_72/CMakeLists.txt | 3 --- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cmake_targets/tools/MODULES/Findxran.cmake b/cmake_targets/tools/MODULES/Findxran.cmake index 290a782350..1ade3ac522 100644 --- a/cmake_targets/tools/MODULES/Findxran.cmake +++ b/cmake_targets/tools/MODULES/Findxran.cmake @@ -75,7 +75,6 @@ endif() find_path(xran_INCLUDE_DIR NAMES - xran_common.h xran_compression.h xran_cp_api.h xran_ecpri_owd_measurements.h @@ -84,7 +83,7 @@ find_path(xran_INCLUDE_DIR xran_pkt_up.h xran_sync_api.h HINTS ${xran_LOCATION} - PATH_SUFFIXES api include + PATH_SUFFIXES api NO_DEFAULT_PATH ) find_library(xran_LIBRARY @@ -127,16 +126,19 @@ find_package_handle_standard_args(xran VERSION_VAR xran_VERSION ) +# in proper usage of cmake, include directory should only contain "api", but not header files under "src" directory; +# however, we use xran_dev_get_ctx() and xran_dev_get_ctx_by_id() functions which are defined in xran_common.h; +# since xran_common.h is under "src" directory, we have to include it in ${xran_INCLUDE_DIRS} if(xran_FOUND) set(xran_LIBRARIES ${xran_LIBRARY}) - set(xran_INCLUDE_DIRS ${xran_INCLUDE_DIR}) + set(xran_INCLUDE_DIRS ${xran_INCLUDE_DIR} ${xran_INCLUDE_DIR}/../src) endif() if(xran_FOUND AND NOT TARGET xran::xran) add_library(xran::xran UNKNOWN IMPORTED) set_target_properties(xran::xran PROPERTIES IMPORTED_LOCATION "${xran_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${xran_INCLUDE_DIR}" + INTERFACE_INCLUDE_DIRECTORIES "${xran_INCLUDE_DIRS}" ) endif() diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index 3fab4f5d47..dd31db27f2 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -36,9 +36,6 @@ target_include_directories(oran_fhlib_5g PRIVATE ${dpdk_INCLUDE_DIRS}) target_link_libraries(oran_fhlib_5g PRIVATE pthread dl rt m numa) target_link_libraries(oran_fhlib_5g PRIVATE ${T_LIB}) -# TODO: can be removed? -target_include_directories(oran_fhlib_5g PRIVATE ${xran_INCLUDE_DIRS}/../src/) - add_boolean_option(OAI_FHI72_USE_POLLING OFF "Enable polling in FHI72 driver" ON) set_target_properties(oran_fhlib_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) From 0be72c1917a148752a13fc2f58998701122daeca Mon Sep 17 00:00:00 2001 From: Teodora Date: Tue, 18 Feb 2025 11:16:22 +0100 Subject: [PATCH 05/27] Install dependencies for M-plane support --- cmake_targets/tools/build_helper | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 3fc1db7b56..057c4860d6 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -546,7 +546,10 @@ check_install_additional_tools (){ libforms-bin \ libforms-dev \ libxft-dev \ - xmlstarlet" + xmlstarlet \ + libpcre3-dev \ + libssh-dev \ + libxml2-dev" elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]] || [[ "$OS_DISTRO" == "rocky" ]] || [[ "$OS_DISTRO" == "fedora" ]]; then PACKAGE_LIST="\ doxygen \ @@ -556,7 +559,10 @@ check_install_additional_tools (){ libXft-devel \ xforms \ xforms-devel \ - xmlstarlet" + xmlstarlet \ + pcre-devel \ + libssh-devel \ + libxml2-devel" fi $SUDO $INSTALLER install -y $PACKAGE_LIST $optional_packages } From da63bf9f9ff83f2e1a4b88292e086475519e1c2a Mon Sep 17 00:00:00 2001 From: Teodora Date: Sat, 15 Feb 2025 17:23:42 +0100 Subject: [PATCH 06/27] M-plane integration - initial commit --- cmake_targets/build_oai | 6 +- radio/fhi_72/CMakeLists.txt | 12 ++- radio/fhi_72/mplane/CMakeLists.txt | 64 ++++++++++++++ radio/fhi_72/mplane/init-mplane.c | 131 ++++++++++++++++++++++++++++ radio/fhi_72/mplane/init-mplane.h | 30 +++++++ radio/fhi_72/mplane/ru-mplane-api.h | 95 ++++++++++++++++++++ radio/fhi_72/oran_isolate.c | 61 +++++++------ 7 files changed, 363 insertions(+), 36 deletions(-) create mode 100644 radio/fhi_72/mplane/CMakeLists.txt create mode 100644 radio/fhi_72/mplane/init-mplane.c create mode 100644 radio/fhi_72/mplane/init-mplane.h create mode 100644 radio/fhi_72/mplane/ru-mplane-api.h diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index d92e488e90..003527056f 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -99,7 +99,7 @@ Options: USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default) Adds this RF board support (in external packages installation and in compilation) -t | --transport - Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g + Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g, oran_fhlib_5g_mplane -P | --phy_simulators Makes the unitary tests Layer 1 simulators -s | --check @@ -304,6 +304,10 @@ function main() { TARGET_LIST="$TARGET_LIST $2" CMAKE_CMD="$CMAKE_CMD -DOAI_FHI72=ON" ;; + "oran_fhlib_5g_mplane") + TARGET_LIST="$TARGET_LIST $2" + CMAKE_CMD="$CMAKE_CMD -DOAI_FHI72=ON -DOAI_FHI72_MPLANE=ON" + ;; "None") ;; *) diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index dd31db27f2..8b047a9316 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -30,15 +30,19 @@ endif() add_compile_options(-Wno-packed-not-aligned) set_target_properties(oran_fhlib_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native") -target_link_libraries(oran_fhlib_5g PRIVATE xran::xran) -target_link_libraries(oran_fhlib_5g PRIVATE ${dpdk_LINK_LIBRARIES}) +target_link_libraries(oran_fhlib_5g PRIVATE xran::xran ${dpdk_LINK_LIBRARIES} ${T_LIB} pthread dl rt m numa) target_include_directories(oran_fhlib_5g PRIVATE ${dpdk_INCLUDE_DIRS}) -target_link_libraries(oran_fhlib_5g PRIVATE pthread dl rt m numa) -target_link_libraries(oran_fhlib_5g PRIVATE ${T_LIB}) add_boolean_option(OAI_FHI72_USE_POLLING OFF "Enable polling in FHI72 driver" ON) +message(STATUS "Building FHI72 CUS library") + set_target_properties(oran_fhlib_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) add_custom_command(TARGET oran_fhlib_5g POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink liboran_fhlib_5g.so liboai_transpro.so WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + +add_boolean_option(OAI_FHI72_MPLANE OFF "Activate OAI's FHI 7.2 M-plane support" OFF) +if(OAI_FHI72_MPLANE) + add_subdirectory(mplane) +endif() diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt new file mode 100644 index 0000000000..7cc53dd40f --- /dev/null +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -0,0 +1,64 @@ +add_library(oran_fhlib_5g_mplane MODULE + ../oran_isolate.c + ../oaioran.c + ../oran-config.c + ../oran-init.c +) +add_dependencies(oran_fhlib_5g_mplane oran_fhlib_5g) + +if(xran_VERSION VERSION_EQUAL 5.1.4) + target_compile_definitions(oran_fhlib_5g_mplane PRIVATE E_RELEASE) +elseif(xran_VERSION VERSION_EQUAL 6.1.1) + target_compile_definitions(oran_fhlib_5g_mplane PRIVATE F_RELEASE) +endif() + +# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress +# alignment 1 of 'struct XYZ' is less than 2 +add_compile_options(-Wno-packed-not-aligned) + +set_target_properties(oran_fhlib_5g_mplane PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native") +target_link_libraries(oran_fhlib_5g_mplane PRIVATE xran::xran ${dpdk_LINK_LIBRARIES} ${T_LIB} pthread dl rt m numa) +target_include_directories(oran_fhlib_5g_mplane PRIVATE ${dpdk_INCLUDE_DIRS}) + +target_compile_definitions(oran_fhlib_5g_mplane PRIVATE OAI_MPLANE) + +################################################### + +target_sources(oran_fhlib_5g_mplane PRIVATE + init-mplane.c +) + +pkg_check_modules(libyang REQUIRED libyang) +pkg_check_modules(libnetconf2 REQUIRED libnetconf2) + +if(libyang_VERSION VERSION_LESS_EQUAL 1.0.240 AND libnetconf2_VERSION VERSION_LESS_EQUAL 1.1.46) + target_compile_definitions(oran_fhlib_5g_mplane PRIVATE MPLANE_V1) +elseif((libyang_VERSION VERSION_GREATER 1.0.240 AND libyang_VERSION VERSION_LESS 2.1.4)) + message(FATAL_ERROR "Minimum libyang v2 subversion required is v2.1.4, but found ${libyang_VERSION}") +elseif((libnetconf2_VERSION VERSION_GREATER 1.1.46 AND libnetconf2_VERSION VERSION_LESS 2.1.25)) + message(FATAL_ERROR "Minimum libnetconf2 v2 subversion required is v2.1.25, but found ${libnetconf2_VERSION}") +elseif((libyang_VERSION VERSION_GREATER_EQUAL 2.1.4 AND libyang_VERSION VERSION_LESS_EQUAL 2.1.111) AND (libnetconf2_VERSION VERSION_GREATER_EQUAL 2.1.25 AND libnetconf2_VERSION VERSION_LESS_EQUAL 2.1.37)) + target_compile_definitions(oran_fhlib_5g_mplane PRIVATE MPLANE_V2) +else() + message(FATAL_ERROR "Unknown libyang version ${libyang_VERSION} and libnetconf2 version ${libnetconf2_VERSION}") +endif() + +target_include_directories(oran_fhlib_5g_mplane PRIVATE ${libyang_INCLUDE_DIRS} ${libnetconf2_INCLUDE_DIRS}) +target_link_libraries(oran_fhlib_5g_mplane PRIVATE ${libyang_LDFLAGS} ${libyang_LINK_LIBRARIES} ${libnetconf2_LINK_LIBRARIES}) + +pkg_check_modules(libssh REQUIRED libssh) +target_include_directories(oran_fhlib_5g_mplane PRIVATE ${libssh_INCLUDE_DIRS}) +target_link_libraries(oran_fhlib_5g_mplane PRIVATE ${libssh_LINK_LIBRARIES}) + +find_package(LibXml2 REQUIRED) +target_link_libraries(oran_fhlib_5g_mplane PRIVATE LibXml2::LibXml2) + +set(YANG_MODELS "${CMAKE_SOURCE_DIR}/radio/fhi_72/mplane/yang/models") +target_compile_definitions(oran_fhlib_5g_mplane PRIVATE YANG_MODELS="${YANG_MODELS}") + +message(STATUS "Building FHI72 CUSM library") + +set_target_properties(oran_fhlib_5g_mplane PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +add_custom_command(TARGET oran_fhlib_5g_mplane POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink liboran_fhlib_5g_mplane.so liboai_transpro.so + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c new file mode 100644 index 0000000000..31988f3dba --- /dev/null +++ b/radio/fhi_72/mplane/init-mplane.c @@ -0,0 +1,131 @@ +/* + * 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 "init-mplane.h" +#include "radio/fhi_72/oran-params.h" + +#include +#include + +static void lnc2_print_clb(NC_VERB_LEVEL level, const char *msg) +{ + switch (level) { + case NC_VERB_ERROR: + MP_LOG_I("[LIBNETCONF2] ERROR: %s.\n", msg); + break; + case NC_VERB_WARNING: + MP_LOG_I("[LIBNETCONF2] WARNING: %s.\n", msg); + break; + case NC_VERB_VERBOSE: + MP_LOG_I("[LIBNETCONF2] VERBOSE: %s.\n", msg); + break; + case NC_VERB_DEBUG: + case NC_VERB_DEBUG_LOWLVL: + MP_LOG_I("[LIBNETCONF2] DEBUG: %s.\n", msg); + break; + default: + assert(false && "[LIBNETCONF2] Unknown log level."); + } +} + +static void ly_print_clb(LY_LOG_LEVEL level, const char *msg, const char *path) +{ + switch (level) { + case LY_LLERR: + MP_LOG_I("[LIBYANG] ERROR: %s (path: %s).\n", msg, path); + break; + case LY_LLWRN: + MP_LOG_I("[LIBYANG] WARNING: %s (path: %s).\n", msg, path); + break; + case LY_LLVRB: + MP_LOG_I("[LIBYANG] VERBOSE: %s (path: %s).\n", msg, path); + break; + case LY_LLDBG: + MP_LOG_I("[LIBYANG] DEBUG: %s (path: %s).\n", msg, path); + break; + default: + assert(false && "[LIBYANG] Unknown log level."); + } +} + +static const paramdef_t *gpd(const paramdef_t *pd, int num, const char *name) +{ + /* the config module does not know const-correctness... */ + int idx = config_paramidx_fromname((paramdef_t *)pd, num, (char *)name); + DevAssert(idx >= 0); + return &pd[idx]; +} + +bool init_mplane(ru_session_list_t *ru_session_list) +{ + paramdef_t fhip[] = ORAN_GLOBALPARAMS_DESC; + int nump = sizeofArray(fhip); + int ret = config_get(config_get_if(), fhip, nump, CONFIG_STRING_ORAN); + if (ret <= 0) { + MP_LOG_I("Problem reading section \"%s\".\n", CONFIG_STRING_ORAN); + return false; + } + + ru_session_list->du_key_pair = gpd(fhip, nump, ORAN_CONFIG_DU_KEYPAIR)->strlistptr; + int num_keys = gpd(fhip, nump, ORAN_CONFIG_DU_KEYPAIR)->numelt; + AssertError(num_keys == 2, return false, "[MPLANE] Expected {pub-key-path, priv-key-path}. Loaded {%s, %s}.\n", ru_session_list->du_key_pair[0], ru_session_list->du_key_pair[1]); + + char **ru_ip_addrs = gpd(fhip, nump, ORAN_CONFIG_RU_IP_ADDR)->strlistptr; + int num_rus = gpd(fhip, nump, ORAN_CONFIG_RU_IP_ADDR)->numelt; + char **du_mac_addr = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->strlistptr; + int num_dus = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->numelt; + int32_t *vlan_tag = gpd(fhip, nump, ORAN_CONFIG_VLAN_TAG)->iptr; + int num_vlan_tags = gpd(fhip, nump, ORAN_CONFIG_VLAN_TAG)->numelt; + + AssertError(num_dus == num_vlan_tags, return false, "[MPLANE] Number of DU MAC addresses should be equal to the number of VLAN tags.\n"); + + int num_cu_planes = num_dus / num_rus; + + ru_session_list->num_rus = num_rus; + ru_session_list->ru_session = calloc(num_rus, sizeof(ru_session_t)); + for (size_t i = 0; i < num_rus; i++) { + ru_session_t *ru_session = &ru_session_list->ru_session[i]; + ru_session->session = NULL; + ru_session->ru_ip_add = calloc(strlen(ru_ip_addrs[i]) + 1, sizeof(char)); + memcpy(ru_session->ru_ip_add, ru_ip_addrs[i], strlen(ru_ip_addrs[i]) + 1); + + // store DU MAC addresses and VLAN tags + ru_session->ru_mplane_config.num_cu_planes = num_cu_planes; + ru_session->ru_mplane_config.du_mac_addr = calloc_or_fail(num_cu_planes, sizeof(char*)); + ru_session->ru_mplane_config.vlan_tag = calloc_or_fail(num_cu_planes, sizeof(int32_t)); + for (int j = 0; j < num_cu_planes; j++) { + const int idx = i*num_cu_planes+j; + ru_session->ru_mplane_config.du_mac_addr[j] = calloc(1, strlen(du_mac_addr[idx]) + 1); + memcpy(ru_session->ru_mplane_config.du_mac_addr[j], du_mac_addr[idx], strlen(du_mac_addr[idx]) + 1); + ru_session->ru_mplane_config.vlan_tag[j] = vlan_tag[idx]; + } + } + + nc_client_init(); + int keypair_ret = nc_client_ssh_add_keypair(ru_session_list->du_key_pair[0], ru_session_list->du_key_pair[1]); + AssertError(keypair_ret == 0, return false, "[MPLANE] Unable to add DU ssh key pair.\n"); + + // logs for netconf2 and yang libraries + nc_set_print_clb(lnc2_print_clb); + ly_set_log_clb(ly_print_clb, 1); + + return true; +} diff --git a/radio/fhi_72/mplane/init-mplane.h b/radio/fhi_72/mplane/init-mplane.h new file mode 100644 index 0000000000..ee558fd77d --- /dev/null +++ b/radio/fhi_72/mplane/init-mplane.h @@ -0,0 +1,30 @@ +/* + * 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 + */ + +#ifndef OAI_MPLANE_H +#define OAI_MPLANE_H + +#include "ru-mplane-api.h" +#include "radio/COMMON/common_lib.h" + +bool init_mplane(ru_session_list_t *ru_session_list); + +#endif /* OAI_MPLANE_H */ diff --git a/radio/fhi_72/mplane/ru-mplane-api.h b/radio/fhi_72/mplane/ru-mplane-api.h new file mode 100644 index 0000000000..4b3b1719c1 --- /dev/null +++ b/radio/fhi_72/mplane/ru-mplane-api.h @@ -0,0 +1,95 @@ +/* + * 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 + */ + +#ifndef RU_MPLANE_API_H +#define RU_MPLANE_API_H + +#include +#include +#include + +#include "common/utils/LOG/log.h" + +#define MP_LOG_I(x, args...) LOG_I(HW, "[MPLANE] " x, ##args) +#define MP_LOG_W(x, args...) LOG_W(HW, "[MPLANE] " x, ##args) + +typedef struct { + bool ptp_state; + bool rx_carrier_state; + bool tx_carrier_state; + // to be extended with any notification callback + +} ru_notif_t; + +typedef struct { + char *ru_mac_addr; + uint32_t mtu; + int16_t iq_width; + uint8_t prach_offset; + + // DU sends to RU and xran + uint16_t du_port_bitmask; + uint16_t band_sector_bitmask; + uint16_t ccid_bitmask; + uint16_t ru_port_bitmask; + + // DU retrieves from RU, and sends to xran + uint8_t du_port; + uint8_t band_sector; + uint8_t ccid; + uint8_t ru_port; + +} xran_mplane_t; + +typedef struct { + size_t num; + char **name; +} uplane_info_t; + +typedef struct { + size_t num_cu_planes; + char **du_mac_addr; // one or two VF(s) for CU-planes + int32_t *vlan_tag; // one or two VF(s) for CU-planes + char *interface_name; + uplane_info_t tx_endpoints; + uplane_info_t rx_endpoints; + uplane_info_t tx_carriers; + uplane_info_t rx_carriers; + +} ru_mplane_config_t; + +typedef struct { + char *ru_ip_add; + ru_mplane_config_t ru_mplane_config; + void *session; + xran_mplane_t xran_mplane; + ru_notif_t ru_notif; + +} ru_session_t; + +typedef struct { + size_t num_rus; + ru_session_t *ru_session; + char **du_key_pair; + +} ru_session_list_t; + +#endif /* RU_MPLANE_API_H */ diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index d3f4fa1796..0221892c37 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -39,6 +39,10 @@ // line and the use of VERSIONX further below. It is relative to phy/fhi_lib/lib/api #include "../../app/src/common.h" +#ifdef OAI_MPLANE +#include "mplane/init-mplane.h" +#endif + typedef struct { eth_state_t e; rru_config_msg_type_t last_msg; @@ -279,7 +283,32 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d openair0_config_t *openair0_cfg, eth_params_t *eth_params) { - oran_eth_state_t *eth; + oran_eth_state_t *eth = calloc_or_fail(1, sizeof(*eth)); + + struct xran_fh_init fh_init = {0}; + struct xran_fh_config fh_config[XRAN_PORTS_NUM] = {0}; + + bool success = false; +#ifdef OAI_MPLANE + ru_session_list_t ru_session_list = {0}; + success = init_mplane(&ru_session_list); + AssertFatal(success, "[MPLANE] Cannot initialize M-plane.\n"); +#else + success = get_xran_config(openair0_cfg, &fh_init, fh_config); + AssertFatal(success, "cannot get configuration for xran\n"); +#endif + + LOG_I(HW, "Initializing O-RAN 7.2 FH interface through xran library (compiled against headers of %s)\n", VERSIONX); + eth->oran_priv = oai_oran_initialize(&fh_init, fh_config); + AssertFatal(eth->oran_priv != NULL, "can not initialize fronthaul"); + // create message queues for ORAN sync + + initNotifiedFIFO(&oran_sync_fifo); + + eth->e.flags = ETH_RAW_IF4p5_MODE; + eth->e.compression = NO_COMPRESS; + eth->e.if_name = eth_params->local_if_name; + eth->last_msg = (rru_config_msg_type_t)-1; device->Mod_id = 0; device->transp_type = ETHERNET_TP; @@ -290,43 +319,13 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d device->trx_stop_func = trx_oran_stop; device->trx_set_freq_func = trx_oran_set_freq; device->trx_set_gains_func = trx_oran_set_gains; - device->trx_write_func = trx_oran_write_raw; device->trx_read_func = trx_oran_read_raw; - device->trx_ctlsend_func = trx_oran_ctlsend; device->trx_ctlrecv_func = trx_oran_ctlrecv; - device->get_internal_parameter = get_internal_parameter; - - eth = (oran_eth_state_t *)calloc(1, sizeof(oran_eth_state_t)); - if (eth == NULL) { - AssertFatal(0 == 1, "out of memory\n"); - } - - eth->e.flags = ETH_RAW_IF4p5_MODE; - eth->e.compression = NO_COMPRESS; - eth->e.if_name = eth_params->local_if_name; - eth->oran_priv = NULL; // define_oran_pointer(); device->priv = eth; device->openair0_cfg = &openair0_cfg[0]; - eth->last_msg = (rru_config_msg_type_t)-1; - - LOG_I(HW, "Initializing O-RAN 7.2 FH interface through xran library (compiled against headers of %s)\n", VERSIONX); - - initNotifiedFIFO(&oran_sync_fifo); - - struct xran_fh_init fh_init = {0}; - struct xran_fh_config fh_config[XRAN_PORTS_NUM] = {0}; -#ifndef OAI_MPLANE_SUPPORT - bool success = get_xran_config(openair0_cfg, &fh_init, fh_config); - AssertFatal(success, "cannot get configuration for xran\n"); -#else - /* TODO: M-plane integration */ -#endif - eth->oran_priv = oai_oran_initialize(&fh_init, fh_config); - AssertFatal(eth->oran_priv != NULL, "can not initialize fronthaul"); - // create message queues for ORAN sync return 0; } From 3f98ec50ef5cab9e2813dbb74c0b4cfd2745c024 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 12:15:42 +0100 Subject: [PATCH 07/27] Add ssh connect function for M-plane --- radio/fhi_72/mplane/CMakeLists.txt | 1 + radio/fhi_72/mplane/connect-mplane.c | 57 ++++++++++++++++++++++++++++ radio/fhi_72/mplane/connect-mplane.h | 29 ++++++++++++++ radio/fhi_72/oran_isolate.c | 10 +++++ 4 files changed, 97 insertions(+) create mode 100644 radio/fhi_72/mplane/connect-mplane.c create mode 100644 radio/fhi_72/mplane/connect-mplane.h diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index 7cc53dd40f..b699c35094 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -26,6 +26,7 @@ target_compile_definitions(oran_fhlib_5g_mplane PRIVATE OAI_MPLANE) target_sources(oran_fhlib_5g_mplane PRIVATE init-mplane.c + connect-mplane.c ) pkg_check_modules(libyang REQUIRED libyang) diff --git a/radio/fhi_72/mplane/connect-mplane.c b/radio/fhi_72/mplane/connect-mplane.c new file mode 100644 index 0000000000..7f4e5e40e6 --- /dev/null +++ b/radio/fhi_72/mplane/connect-mplane.c @@ -0,0 +1,57 @@ +/* + * 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 "connect-mplane.h" +#include "common/utils/assertions.h" + +#include +#include + +static int my_auth_hostkey_check(const char *hostname, ssh_session session, void *priv) +{ + (void)hostname; + (void)session; + (void)priv; + + return 0; +} + +bool connect_mplane(ru_session_t *ru_session) +{ + int port = NC_PORT_SSH; + char *user = "oranbenetel"; + + nc_client_ssh_set_username(user); + + nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1); // ssh-key identification + nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1); + nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, -1); + + nc_client_ssh_set_auth_hostkey_check_clb(my_auth_hostkey_check, "DATA"); // host-key identification + + MP_LOG_I("RPC request to RU \"%s\" = with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, user, port); + ru_session->session = nc_connect_ssh(ru_session->ru_ip_add, port, NULL); + AssertError(ru_session->session != NULL, return false, "[MPLANE] RU IP address %s unreachable. Maybe M-plane is disabled on the RU?\n", ru_session->ru_ip_add); + + MP_LOG_I("Successfuly connected to RU \"%s\" with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, user, port); + + return true; +} diff --git a/radio/fhi_72/mplane/connect-mplane.h b/radio/fhi_72/mplane/connect-mplane.h new file mode 100644 index 0000000000..5283e6ef75 --- /dev/null +++ b/radio/fhi_72/mplane/connect-mplane.h @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#ifndef CONNECT_MPLANE_H +#define CONNECT_MPLANE_H + +#include "ru-mplane-api.h" + +bool connect_mplane(ru_session_t *ru_session); + +#endif /* CONNECT_MPLANE_H */ diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 0221892c37..a249924731 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -41,6 +41,7 @@ #ifdef OAI_MPLANE #include "mplane/init-mplane.h" +#include "mplane/connect-mplane.h" #endif typedef struct { @@ -293,6 +294,15 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d ru_session_list_t ru_session_list = {0}; success = init_mplane(&ru_session_list); AssertFatal(success, "[MPLANE] Cannot initialize M-plane.\n"); + + bool ru_configured[ru_session_list.num_rus]; + for (size_t i = 0; i < ru_session_list.num_rus; i++) { + ru_session_t *ru_session = &ru_session_list.ru_session[i]; + ru_configured[i] = connect_mplane(ru_session); + if (!ru_configured[i]) { + continue; + } + } #else success = get_xran_config(openair0_cfg, &fh_init, fh_config); AssertFatal(success, "cannot get configuration for xran\n"); From 93aaaef50e1e23b2d275777fc515fc567f703e88 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 13:06:59 +0100 Subject: [PATCH 08/27] Add RPC send and receive functionalities --- radio/fhi_72/mplane/CMakeLists.txt | 1 + radio/fhi_72/mplane/rpc-send-recv.c | 296 ++++++++++++++++++++++++++++ radio/fhi_72/mplane/rpc-send-recv.h | 34 ++++ 3 files changed, 331 insertions(+) create mode 100644 radio/fhi_72/mplane/rpc-send-recv.c create mode 100644 radio/fhi_72/mplane/rpc-send-recv.h diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index b699c35094..f58238024e 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -27,6 +27,7 @@ target_compile_definitions(oran_fhlib_5g_mplane PRIVATE OAI_MPLANE) target_sources(oran_fhlib_5g_mplane PRIVATE init-mplane.c connect-mplane.c + rpc-send-recv.c ) pkg_check_modules(libyang REQUIRED libyang) diff --git a/radio/fhi_72/mplane/rpc-send-recv.c b/radio/fhi_72/mplane/rpc-send-recv.c new file mode 100644 index 0000000000..4b218fc164 --- /dev/null +++ b/radio/fhi_72/mplane/rpc-send-recv.c @@ -0,0 +1,296 @@ +/* + * 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 "rpc-send-recv.h" + +#include "common/utils/assertions.h" + + +#ifdef MPLANE_V1 +static bool recv_v1(struct nc_session *session, struct nc_rpc *rpc, NC_MSG_TYPE msgtype, const uint64_t msgid, const NC_WD_MODE wd_mode, const int timeout_ms, char **answer) +{ + struct nc_reply *reply; + struct nc_reply_data *data_rpl; + struct nc_reply_error *error; + LYD_FORMAT output_format = LYD_XML; + uint32_t ly_wd; + + while (1) { + msgtype = nc_recv_reply(session, rpc, msgid, timeout_ms, 0, &reply); + if (msgtype == NC_MSG_ERROR) { + AssertError(false, return false, "[MPLANE] Failed to receive a reply.\n"); + } else if (msgtype == NC_MSG_WOULDBLOCK) { + AssertError(false, return false, "[MPLANE] Timeout for receiving a reply expired.\n"); + } else if (msgtype == NC_MSG_NOTIF) { + /* read again */ + continue; + } else if (msgtype == NC_MSG_REPLY_ERR_MSGID) { + /* unexpected message, try reading again to get the correct reply */ + MP_LOG_I("Unexpected reply received - ignoring and waiting for the correct reply.\n"); + nc_reply_free(reply); + continue; + } + break; + } + + switch (reply->type) { + case NC_RPL_OK: + MP_LOG_I("RPC reply = OK.\n"); + break; + case NC_RPL_DATA: + data_rpl = (struct nc_reply_data *)reply; + + switch (wd_mode) { + case NC_WD_ALL: + ly_wd = LYP_WD_ALL; + break; + case NC_WD_ALL_TAG: + ly_wd = LYP_WD_ALL_TAG; + break; + case NC_WD_TRIM: + ly_wd = LYP_WD_TRIM; + break; + case NC_WD_EXPLICIT: + ly_wd = LYP_WD_EXPLICIT; + break; + default: + ly_wd = 0; // when wd_mode = NC_WD_UNKNOWN + break; + } + + if (nc_rpc_get_type(rpc) == NC_RPC_GETSCHEMA) { + AssertError((!data_rpl->data || (data_rpl->data->schema->nodetype != LYS_RPC) || (data_rpl->data->child == NULL) + || (data_rpl->data->child->schema->nodetype != LYS_ANYXML)), return false, "[MPLANE] Cannot get schema.\n"); + + struct lyd_node_anydata *any = (struct lyd_node_anydata *)data_rpl->data->child; + switch (any->value_type) { + case LYD_ANYDATA_CONSTSTRING: + case LYD_ANYDATA_STRING: + *answer = strdup(any->value.str); + break; + case LYD_ANYDATA_DATATREE: + lyd_print_mem(answer, any->value.tree, output_format, LYP_WITHSIBLINGS); + break; + case LYD_ANYDATA_XML: + lyxml_print_mem(answer, any->value.xml, LYXML_PRINT_SIBLINGS); + break; + default: + AssertError(false, return false, "[MPLANE] Unknown yang type.\n"); + } + break; + } else if (nc_rpc_get_type(rpc) == NC_RPC_GETCONFIG || nc_rpc_get_type(rpc) == NC_RPC_GET) { + const char *tag = nc_rpc_get_type(rpc) == NC_RPC_GETCONFIG ? "config" : "data"; + char *buffer = NULL; + lyd_print_mem(&buffer, data_rpl->data, output_format, LYP_WITHSIBLINGS | LYP_NETCONF | ly_wd); + *answer = calloc(strlen(buffer)+128, sizeof(char)); + sprintf(*answer, "<%s xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n%s", tag, buffer, tag); + } else { + AssertError(false, return false, "[MPLANE] Unknown RPC type.\n"); + } + + break; + case NC_RPL_ERROR: + error = (struct nc_reply_error *)reply; + for (int i = 0; i < error->count; ++i) { + const struct nc_err *err = &error->err[i]; + MP_LOG_I("RPC reply = ERROR\n\ + \ttype: %s\n\ + \ttag: %s\n\ + \tseverity: %s\n\ + \tapp-tag: %s\n\ + \tpath: %s\n\ + \tmessage: %s\n\ + \tSID: %s\n", + err->type, + err->tag, + err->severity, + err->apptag, + err->path, + err->message, + err->sid); + + for (int j = 0; j < err->attr_count; ++j) { + MP_LOG_I("\tbad-attr #%d: %s\n", j + 1, err->attr[j]); + } + for (int j = 0; j < err->elem_count; ++j) { + MP_LOG_I("\tbad-elem #%d: %s\n", j + 1, err->elem[j]); + } + for (int j = 0; j < err->ns_count; ++j) { + MP_LOG_I("\tbad-ns #%d: %s\n", j + 1, err->ns[j]); + } + for (int j = 0; j < err->other_count; ++j) { + char *str = NULL; + lyxml_print_mem(&str, err->other[j], 0); + MP_LOG_I("\tother #%d:\n%s\n", j + 1, str); + free(str); + } + } + AssertError(false, return false, "[MPLANE] Unable to continue.\n"); + break; + default: + AssertError(false, return false, "[MPLANE] Internal error.\n"); + nc_reply_free(reply); + } + nc_reply_free(reply); + + return true; +} +#elif defined MPLANE_V2 +static bool recv_v2(struct nc_session *session, struct nc_rpc *rpc, NC_MSG_TYPE msgtype, const uint64_t msgid, const NC_WD_MODE wd_mode, const int timeout_ms, char **answer) +{ + struct lyd_node *envp, *op, *err; + LYD_FORMAT output_format = LYD_XML; + uint32_t ly_wd; + + while (1) { + msgtype = nc_recv_reply(session, rpc, msgid, timeout_ms, &envp, &op); + if (msgtype == NC_MSG_ERROR) { + AssertError(false, return false, "[MPLANE] Failed to receive a reply.\n"); + } else if (msgtype == NC_MSG_WOULDBLOCK) { + AssertError(false, return false, "[MPLANE] Timeout for receiving a reply for RPC expired.\n"); + } else if (msgtype == NC_MSG_NOTIF) { // for SUBSCRIBE + /* read again */ + continue; + } else if (msgtype == NC_MSG_REPLY_ERR_MSGID) { + /* unexpected message, try reading again to get the correct reply */ + MP_LOG_I("Unexpected reply received - ignoring and waiting for the correct reply.\n"); + lyd_free_tree(envp); + lyd_free_tree(op); + continue; + } + break; + } + + /* get functionality */ + if (op) { + /* data reply */ + if (nc_rpc_get_type(rpc) == NC_RPC_GETSCHEMA) { + /* special case */ + if (!lyd_child(op) || (lyd_child(op)->schema->nodetype != LYS_ANYXML)) { + AssertError(false, return false, "[MPLANE] Cannot get schema."); + } + struct lyd_node_any *any = (struct lyd_node_any *)lyd_child(op); + switch (any->value_type) { + case LYD_ANYDATA_STRING: + case LYD_ANYDATA_XML: + *answer = strdup(any->value.str); + break; + case LYD_ANYDATA_DATATREE: + lyd_print_mem(answer, any->value.tree, output_format, LYD_PRINT_WITHSIBLINGS); + break; + default: + AssertError(false, return false, "[MPLANE] Unexpected yang type."); + } + } else { + switch (wd_mode) { + case NC_WD_ALL: + ly_wd = LYD_PRINT_WD_ALL; + break; + case NC_WD_ALL_TAG: + ly_wd = LYD_PRINT_WD_ALL_TAG; + break; + case NC_WD_TRIM: + ly_wd = LYD_PRINT_WD_TRIM; + break; + case NC_WD_EXPLICIT: + ly_wd = LYD_PRINT_WD_EXPLICIT; + break; + default: + ly_wd = 0; // when wd_mode = NC_WD_UNKNOWN + break; + } + lyd_print_mem(answer, lyd_child(op), output_format, LYD_PRINT_WITHSIBLINGS | ly_wd); + } + /* edit/validate/commit functionalities */ + } else if (!strcmp(LYD_NAME(lyd_child(envp)), "ok")) { + MP_LOG_I("RPC reply = OK.\n"); + } else { + LY_LIST_FOR(lyd_child(envp), err) { + struct lyd_node *type, *tag, *severity, *app_tag, *path, *er_msg, *info = NULL; + lyd_find_sibling_opaq_next(lyd_child(err), "error-type", &type); + lyd_find_sibling_opaq_next(lyd_child(err), "error-tag", &tag); + lyd_find_sibling_opaq_next(lyd_child(err), "error-severity", &severity); + lyd_find_sibling_opaq_next(lyd_child(err), "error-app-tag", &app_tag); + lyd_find_sibling_opaq_next(lyd_child(err), "error-path", &path); + lyd_find_sibling_opaq_next(lyd_child(err), "error-message", &er_msg); + + MP_LOG_I("RPC reply = ERROR\n\ + \ttype: %s\n\ + \ttag: %s\n\ + \tseverity: %s\n\ + \tapp-tag: %s\n\ + \tpath: %s\n\ + \tmessage: %s\n", + (type ? ((struct lyd_node_opaq *)type)->value : NULL), + (tag ? ((struct lyd_node_opaq *)tag)->value : NULL), + (severity ? ((struct lyd_node_opaq *)severity)->value : NULL), + (app_tag ? ((struct lyd_node_opaq *)app_tag)->value : NULL), + (path ? ((struct lyd_node_opaq *)path)->value : NULL), + (er_msg ? ((struct lyd_node_opaq *)er_msg)->value : NULL)); + + info = lyd_child(err); + while (!lyd_find_sibling_opaq_next(info, "error-info", &info)) { + char *str = NULL; + lyd_print_mem(&str, lyd_child(info), output_format, LYD_PRINT_WITHSIBLINGS); + MP_LOG_I("\tinfo: %s\n", str); + info = info->next; + free(str); + } + lyd_free_tree(type); + lyd_free_tree(tag); + lyd_free_tree(severity); + lyd_free_tree(app_tag); + lyd_free_tree(path); + lyd_free_tree(er_msg); + lyd_free_tree(info); + } + lyd_free_tree(envp); + lyd_free_tree(op); + AssertError(false, return false, "[MPLANE] Unable to continue.\n"); + } + + lyd_free_tree(envp); + lyd_free_tree(op); + + return true; +} +#endif + +bool rpc_send_recv(struct nc_session *session, struct nc_rpc *rpc, const NC_WD_MODE wd_mode, const int timeout_ms, char **answer) +{ + uint64_t msgid; + NC_MSG_TYPE msgtype; + + msgtype = nc_send_rpc(session, rpc, 1000, &msgid); + if (msgtype == NC_MSG_ERROR) { + AssertError(false, return false, "[MPLANE] Failed to send the RPC.\n"); + } else if (msgtype == NC_MSG_WOULDBLOCK) { + AssertError(false, return false, "[MPLANE] Timeout for sending the RPC expired.\n"); + } + +#ifdef MPLANE_V1 + return recv_v1(session, rpc, msgtype, msgid, wd_mode, timeout_ms, answer); +#elif defined MPLANE_V2 + return recv_v2(session, rpc, msgtype, msgid, wd_mode, timeout_ms, answer); +#else + AssertError(false, return false, "[MPLANE] Unknown M-plane version found. Tried \"MPLANE_V1\" and \"MPLANE_V2\".\n"); +#endif +} diff --git a/radio/fhi_72/mplane/rpc-send-recv.h b/radio/fhi_72/mplane/rpc-send-recv.h new file mode 100644 index 0000000000..4cf2095713 --- /dev/null +++ b/radio/fhi_72/mplane/rpc-send-recv.h @@ -0,0 +1,34 @@ +/* + * 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 + */ + +#ifndef RPC_SEND_RECEIVE_MPLANE_H +#define RPC_SEND_RECEIVE_MPLANE_H + +#include "ru-mplane-api.h" + +#include +#include + +#define CLI_RPC_REPLY_TIMEOUT 60000 // time [ms] to wait for server reply + +bool rpc_send_recv(struct nc_session *session, struct nc_rpc *rpc, const NC_WD_MODE wd_mode, const int timeout_ms, char **answer); + +#endif /* RPC_SEND_RECEIVE_MPLANE_H */ From 064866459c71513d347e6a68095b4aac8bf47a0c Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 14:40:00 +0100 Subject: [PATCH 09/27] Add RPC for M-plane --- radio/fhi_72/mplane/CMakeLists.txt | 1 + radio/fhi_72/mplane/get-mplane.c | 47 ++++++++++++++++++++++++++++++ radio/fhi_72/mplane/get-mplane.h | 29 ++++++++++++++++++ radio/fhi_72/mplane/init-mplane.c | 14 +++++++++ radio/fhi_72/mplane/init-mplane.h | 2 ++ radio/fhi_72/oran_isolate.c | 1 + 6 files changed, 94 insertions(+) create mode 100644 radio/fhi_72/mplane/get-mplane.c create mode 100644 radio/fhi_72/mplane/get-mplane.h diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index f58238024e..2699beb6d9 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -28,6 +28,7 @@ target_sources(oran_fhlib_5g_mplane PRIVATE init-mplane.c connect-mplane.c rpc-send-recv.c + get-mplane.c ) pkg_check_modules(libyang REQUIRED libyang) diff --git a/radio/fhi_72/mplane/get-mplane.c b/radio/fhi_72/mplane/get-mplane.c new file mode 100644 index 0000000000..06aa6d0317 --- /dev/null +++ b/radio/fhi_72/mplane/get-mplane.c @@ -0,0 +1,47 @@ +/* + * 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 "get-mplane.h" +#include "rpc-send-recv.h" + +#include "common/utils/assertions.h" + +bool get_mplane(ru_session_t *ru_session, char **answer) +{ + int timeout = CLI_RPC_REPLY_TIMEOUT; + struct nc_rpc *rpc; + char *filter = NULL; // e.g. "/o-ran-delay-management:delay-management"; + NC_WD_MODE wd = NC_WD_ALL; + NC_PARAMTYPE param = NC_PARAMTYPE_CONST; + + MP_LOG_I("RPC request to RU \"%s\" = operational datastore.\n", ru_session->ru_ip_add); + rpc = nc_rpc_get(filter, wd, param); + AssertError(rpc != NULL, return false, "[MPLANE] RPC creation failed.\n"); + + bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, answer); + AssertError(success, return false, "[MPLANE] Unable to retrieve operational datastore.\n"); + + MP_LOG_I("Successfully retrieved operational datastore from RU \"%s\".\n", ru_session->ru_ip_add); + + nc_rpc_free(rpc); + + return true; +} diff --git a/radio/fhi_72/mplane/get-mplane.h b/radio/fhi_72/mplane/get-mplane.h new file mode 100644 index 0000000000..a47abdc8f5 --- /dev/null +++ b/radio/fhi_72/mplane/get-mplane.h @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#ifndef GET_MPLANE_H +#define GET_MPLANE_H + +#include "ru-mplane-api.h" + +bool get_mplane(ru_session_t *ru_session, char **answer); + +#endif /* GET_MPLANE_H */ diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index 31988f3dba..cd83ccc4f6 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -21,6 +21,7 @@ #include "init-mplane.h" #include "radio/fhi_72/oran-params.h" +#include "get-mplane.h" #include #include @@ -129,3 +130,16 @@ bool init_mplane(ru_session_list_t *ru_session_list) return true; } + +bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus) +{ + bool success = false; + + char *operational_ds = NULL; + success = get_mplane(ru_session, &operational_ds); + AssertError(success, return false, "[MPLANE] Unable to continue: could not get RU answer via get_mplane().\n"); + + free(operational_ds); + + return true; +} diff --git a/radio/fhi_72/mplane/init-mplane.h b/radio/fhi_72/mplane/init-mplane.h index ee558fd77d..5077908d64 100644 --- a/radio/fhi_72/mplane/init-mplane.h +++ b/radio/fhi_72/mplane/init-mplane.h @@ -27,4 +27,6 @@ bool init_mplane(ru_session_list_t *ru_session_list); +bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus); + #endif /* OAI_MPLANE_H */ diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index a249924731..8104b1a2c2 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -302,6 +302,7 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d if (!ru_configured[i]) { continue; } + ru_configured[i] = manage_ru(ru_session, openair0_cfg, ru_session_list.num_rus); } #else success = get_xran_config(openair0_cfg, &fh_init, fh_config); From fb670db91e7143bf054352997c3edf3b421de28c Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 14:51:42 +0100 Subject: [PATCH 10/27] Get info from xml operational datastore - obtain one or multiple node values --- radio/fhi_72/mplane/CMakeLists.txt | 1 + radio/fhi_72/mplane/xml/get-xml.c | 95 ++++++++++++++++++++++++++++++ radio/fhi_72/mplane/xml/get-xml.h | 48 +++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 radio/fhi_72/mplane/xml/get-xml.c create mode 100644 radio/fhi_72/mplane/xml/get-xml.h diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index 2699beb6d9..1d00c26ab2 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -29,6 +29,7 @@ target_sources(oran_fhlib_5g_mplane PRIVATE connect-mplane.c rpc-send-recv.c get-mplane.c + xml/get-xml.c ) pkg_check_modules(libyang REQUIRED libyang) diff --git a/radio/fhi_72/mplane/xml/get-xml.c b/radio/fhi_72/mplane/xml/get-xml.c new file mode 100644 index 0000000000..616d2e480f --- /dev/null +++ b/radio/fhi_72/mplane/xml/get-xml.c @@ -0,0 +1,95 @@ +/* + * 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 "get-xml.h" + +#include +#include + +static char *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) + continue; + + if (strcmp((const char *)cur_node->name, filter) == 0) { + xmlNode *target_node = cur_node; + + for(xmlNode *cur_node2 = cur_node->children; cur_node2; cur_node2 = cur_node2->next) { + if (cur_node2->type == XML_ELEMENT_NODE && strcmp((const char *)cur_node2->name, "name") == 0) { + target_node = cur_node2; + break; + } + } + return (char *)xmlNodeGetContent(target_node); + } + char *answer = find_ru_xml_node(cur_node->children, filter); + if (answer != NULL) { + return answer; + } + } + return NULL; +} + +char *get_ru_xml_node(const char *buffer, const char *filter) +{ + // Initialize the xml file + size_t len = strlen(buffer) + 1; + xmlDoc *doc = xmlReadMemory(buffer, len, NULL, NULL, 0); + xmlNode *root_element = xmlDocGetRootElement(doc); + + return find_ru_xml_node(root_element->children, filter); +} + +static void find_ru_xml_list(xmlNode *node, const char *filter, char ***match_list, size_t *count) +{ + for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next) { + if (cur_node->type != XML_ELEMENT_NODE) + continue; + if (strcmp((const char *)cur_node->name, filter) == 0) { + xmlNode *name_node = NULL; + + for (xmlNode *cur_node2 = cur_node->children; cur_node2; cur_node2 = cur_node2->next) { + if (cur_node2->type == XML_ELEMENT_NODE && strcmp((const char *)cur_node2->name, "name") == 0) { + name_node = cur_node2; + break; + } + } + const char *content = (const char *)xmlNodeGetContent(name_node ? name_node : cur_node); + if (content) { + *match_list = realloc(*match_list, (*count + 1) * sizeof(char *)); + (*match_list)[*count] = strdup(content); + (*count)++; + } + } + find_ru_xml_list(cur_node->children, filter, match_list, count); + } +} + +void get_ru_xml_list(const char *buffer, const char *filter, char ***match_list, size_t *count) +{ + // Initialize the xml file + size_t len = strlen(buffer) + 1; + xmlDoc *doc = xmlReadMemory(buffer, len, NULL, NULL, 0); + xmlNode *root_element = xmlDocGetRootElement(doc); + + find_ru_xml_list(root_element->children, filter, match_list, count); +} diff --git a/radio/fhi_72/mplane/xml/get-xml.h b/radio/fhi_72/mplane/xml/get-xml.h new file mode 100644 index 0000000000..5241e64af6 --- /dev/null +++ b/radio/fhi_72/mplane/xml/get-xml.h @@ -0,0 +1,48 @@ +/* + * 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 + */ + +#ifndef GET_MPLANE_INFO_XML_H +#define GET_MPLANE_INFO_XML_H + +#include +#include + +/** + * @brief retrieves the node value that matches filter. + * + * @param[in] buffer Buffer in xml format. + * @param[in] filter The node name (matching criteria). + * @return Expected one string that matches the node name. + */ +char *get_ru_xml_node(const char *buffer, const char *filter); + +/** + * @brief retrieves the node values that matches filter. + * + * @param[in] buffer Buffer in xml format. + * @param[in] filter The node name (matching criteria). + * @param[out] match_list Resulting list containing node values. + * @param[out] count The number of nodes that match criteria. + * @return Void. + */ +void get_ru_xml_list(const char *buffer, const char *filter, char ***match_list, size_t *count); + +#endif /* GET_MPLANE_INFO_XML_H */ From 07bab2a707110855d963e9844d0fb34617e7c028 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 15:01:30 +0100 Subject: [PATCH 11/27] Get the current sync status from operational datastore --- radio/fhi_72/mplane/init-mplane.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index cd83ccc4f6..e9c91387db 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -22,6 +22,7 @@ #include "init-mplane.h" #include "radio/fhi_72/oran-params.h" #include "get-mplane.h" +#include "xml/get-xml.h" #include #include @@ -139,6 +140,13 @@ 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; + } + free(operational_ds); return true; From 6266239c34e2b440d0af697c3d36eaa31d4539f9 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 15:21:37 +0100 Subject: [PATCH 12/27] Add RPC for M-plane --- radio/fhi_72/mplane/CMakeLists.txt | 1 + radio/fhi_72/mplane/init-mplane.c | 12 +++ radio/fhi_72/mplane/subscribe-mplane.c | 133 +++++++++++++++++++++++++ radio/fhi_72/mplane/subscribe-mplane.h | 31 ++++++ 4 files changed, 177 insertions(+) create mode 100644 radio/fhi_72/mplane/subscribe-mplane.c create mode 100644 radio/fhi_72/mplane/subscribe-mplane.h diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index 1d00c26ab2..0092f96698 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -29,6 +29,7 @@ target_sources(oran_fhlib_5g_mplane PRIVATE connect-mplane.c rpc-send-recv.c get-mplane.c + subscribe-mplane.c xml/get-xml.c ) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index e9c91387db..72f6d46701 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -22,6 +22,7 @@ #include "init-mplane.h" #include "radio/fhi_72/oran-params.h" #include "get-mplane.h" +#include "subscribe-mplane.h" #include "xml/get-xml.h" #include @@ -147,6 +148,17 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz ptp_state = true; } + /* 1) as per M-plane spec, RU must be in supervised mode, + where stream = NULL && filter = "/o-ran-supervision:supervision-notification"; + 2) additionally, we want to subscribe to PTP state change, + where stream = NULL && filter = "/o-ran-sync:synchronization-state-change"; + => 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"); + free(operational_ds); return true; diff --git a/radio/fhi_72/mplane/subscribe-mplane.c b/radio/fhi_72/mplane/subscribe-mplane.c new file mode 100644 index 0000000000..64215c0aba --- /dev/null +++ b/radio/fhi_72/mplane/subscribe-mplane.c @@ -0,0 +1,133 @@ +/* + * 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 "subscribe-mplane.h" +#include "rpc-send-recv.h" +#include "common/utils/assertions.h" + +#include +#include + +#ifdef MPLANE_V1 +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; + } + } + + // carriers state - to be filled +} + +static void notif_clb_v1(struct nc_session *session, const struct nc_notif *notif) +{ + ru_notif_t *answer = nc_session_get_data(session); + LYD_FORMAT output_format = LYD_JSON; + + char *subs_reply = NULL; + lyd_print_mem(&subs_reply, notif->tree, output_format, LYP_WITHSIBLINGS); + MP_LOG_I("\nReceived notification at (%s)\n%s\n", notif->datetime, subs_reply); + + recv_notif_v1(notif, answer); +} +#elif MPLANE_V2 +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; + } + } 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; + } + } 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; + } + } +} + +static void notif_clb_v2(struct nc_session *session, const struct lyd_node *envp, const struct lyd_node *op, void *user_data) +{ + ru_notif_t *answer = (ru_notif_t *)user_data; + LYD_FORMAT output_format = LYD_JSON; + + char *subs_reply = NULL; + lyd_print_mem(&subs_reply, op, output_format, LYD_PRINT_WITHSIBLINGS); + const char *ru_ip_add = nc_session_get_host(session); + 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((struct lyd_node_inner *)op, answer); +} +#endif + +bool subscribe_mplane(ru_session_t *ru_session, const char *stream, const char *filter, void *answer) +{ + int timeout = CLI_RPC_REPLY_TIMEOUT; + struct nc_rpc *rpc; + NC_WD_MODE wd = NC_WD_ALL; + NC_PARAMTYPE param = NC_PARAMTYPE_CONST; + char *start_time = NULL, *stop_time = NULL; + + MP_LOG_I("RPC request to RU \"%s\" = with stream \"%s\" and filter \"%s\".\n", ru_session->ru_ip_add, stream, filter); + rpc = nc_rpc_subscribe(stream, NULL, start_time, stop_time, param); + AssertError(rpc != NULL, return false, "[MPLANE] RPC creation failed.\n"); + + /* create notification thread so that notifications can immediately be received */ +#ifdef MPLANE_V1 + if (!nc_session_ntf_thread_running(ru_session->session)) { + nc_session_set_data(ru_session->session, answer); + int ret = nc_recv_notif_dispatch(ru_session->session, notif_clb_v1); + AssertError(ret == 0, return false, "[MPLANE] Failed to create notification thread.\n"); + } else { + MP_LOG_I("Notification thread is already running for RU %s.\n", ru_session->ru_ip_add); + } +#elif MPLANE_V2 + int ret = nc_recv_notif_dispatch_data(ru_session->session, notif_clb_v2, answer, NULL); + AssertError(ret == 0, return false, "[MPLANE] Failed to create notification thread.\n"); +#endif + + bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL); + AssertError(success, return false, "[MPLANE] Failed to subscribe to: stream \"%s\", filter \"%s\".\n", stream, filter); + + MP_LOG_I("Successfully subscribed to all notifications from RU \"%s\".\n", ru_session->ru_ip_add); + + nc_rpc_free(rpc); + + return true; +} diff --git a/radio/fhi_72/mplane/subscribe-mplane.h b/radio/fhi_72/mplane/subscribe-mplane.h new file mode 100644 index 0000000000..c5a6762fe9 --- /dev/null +++ b/radio/fhi_72/mplane/subscribe-mplane.h @@ -0,0 +1,31 @@ +/* + * 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 + */ + +#ifndef SUBSCRIBE_MPLANE_H +#define SUBSCRIBE_MPLANE_H + +#include "ru-mplane-api.h" + +#include + +bool subscribe_mplane(ru_session_t *ru_session, const char *stream, const char *filter, void *answer); + +#endif /* SUBSCRIBE_MPLANE_H */ From 2cd5c1faf76498d1be552db5601c2fbf7312e10e Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 15:34:15 +0100 Subject: [PATCH 13/27] Add RPC for M-plane --- radio/fhi_72/mplane/init-mplane.c | 7 +++++++ radio/fhi_72/mplane/subscribe-mplane.c | 25 +++++++++++++++++++++++++ radio/fhi_72/mplane/subscribe-mplane.h | 2 ++ 3 files changed, 34 insertions(+) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index 72f6d46701..453a8b1390 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -159,7 +159,14 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz 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"); + // when subscribed to the supervision notification, the watchdog timer needs to be updated + char *watchdog_answer = NULL; + success = update_timer_mplane(ru_session, &watchdog_answer); + 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); + free(operational_ds); + free(watchdog_answer); return true; } diff --git a/radio/fhi_72/mplane/subscribe-mplane.c b/radio/fhi_72/mplane/subscribe-mplane.c index 64215c0aba..d96d367d35 100644 --- a/radio/fhi_72/mplane/subscribe-mplane.c +++ b/radio/fhi_72/mplane/subscribe-mplane.c @@ -131,3 +131,28 @@ bool subscribe_mplane(ru_session_t *ru_session, const char *stream, const char * return true; } + +bool update_timer_mplane(ru_session_t *ru_session, char **answer) +{ + int timeout = CLI_RPC_REPLY_TIMEOUT; + struct nc_rpc *rpc; + NC_WD_MODE wd = NC_WD_ALL; + NC_PARAMTYPE param = NC_PARAMTYPE_CONST; + const char *content = "\n\ +65535\n\ +65535\n\ +"; + + MP_LOG_I("RPC request to RU \"%s\" = \"%s\".\n", ru_session->ru_ip_add, content); + rpc = nc_rpc_act_generic_xml(content, param); + AssertError(rpc != NULL, return false, "[MPLANE] RPC creation failed.\n"); + + bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, answer); + AssertError(success, return false, "[MPLANE] Failed to update the watchdog timer.\n"); + + MP_LOG_I("Successfully updated supervision timer to (65535+65535)[s] for RU \"%s\".\n", ru_session->ru_ip_add); + + nc_rpc_free(rpc); + + return true; +} diff --git a/radio/fhi_72/mplane/subscribe-mplane.h b/radio/fhi_72/mplane/subscribe-mplane.h index c5a6762fe9..6cb7a10310 100644 --- a/radio/fhi_72/mplane/subscribe-mplane.h +++ b/radio/fhi_72/mplane/subscribe-mplane.h @@ -28,4 +28,6 @@ bool subscribe_mplane(ru_session_t *ru_session, const char *stream, const char *filter, void *answer); +bool update_timer_mplane(ru_session_t *ru_session, char **answer); + #endif /* SUBSCRIBE_MPLANE_H */ From 45d0eaf3c49ba8377cef62b8f20da0153321c070 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 15:46:08 +0100 Subject: [PATCH 14/27] Get and store M-plane related params for xran --- radio/fhi_72/mplane/CMakeLists.txt | 1 + radio/fhi_72/mplane/init-mplane.c | 5 ++ radio/fhi_72/mplane/ru-mplane-api.c | 127 ++++++++++++++++++++++++++++ radio/fhi_72/mplane/ru-mplane-api.h | 2 + 4 files changed, 135 insertions(+) create mode 100644 radio/fhi_72/mplane/ru-mplane-api.c 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 */ From e0ffba49ae4593ea959b993c7949b6683f7d3b44 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 15:51:52 +0100 Subject: [PATCH 15/27] Store U-plane related info from xml - interface name, - TX/RX carrier names, and - TX/RX endpoint names --- radio/fhi_72/mplane/init-mplane.c | 4 ++++ radio/fhi_72/mplane/ru-mplane-api.c | 30 +++++++++++++++++++++++++++++ radio/fhi_72/mplane/ru-mplane-api.h | 2 ++ 3 files changed, 36 insertions(+) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index 34d68a30d0..add3916f4d 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -170,6 +170,10 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz 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); + // save the U-plane info + success = get_uplane_info(operational_ds, &ru_session->ru_mplane_config); + AssertError(success, return false, "[MPLANE] Unable to get U-plane info from RU operational datastore.\n"); + 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 index ada42fd841..d387a40864 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.c +++ b/radio/fhi_72/mplane/ru-mplane-api.c @@ -125,3 +125,33 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ return true; } + +bool get_uplane_info(const char *buffer, ru_mplane_config_t *ru_mplane_config) +{ + // Interface name + ru_mplane_config->interface_name = get_ru_xml_node(buffer, "interface"); + + // PDSCH + uplane_info_t *tx_end = &ru_mplane_config->tx_endpoints; + get_ru_xml_list(buffer, "static-low-level-tx-endpoints", &tx_end->name, &tx_end->num); + AssertError(tx_end->name != NULL, return false, "[MPLANE] Cannot get TX endpoint names.\n"); + + // TX carriers + uplane_info_t *tx_carriers = &ru_mplane_config->tx_carriers; + get_ru_xml_list(buffer, "tx-arrays", &tx_carriers->name, &tx_carriers->num); + AssertError(tx_carriers->name != NULL, return false, "[MPLANE] Cannot get TX carrier names.\n"); + + // PUSCH and PRACH + uplane_info_t *rx_end = &ru_mplane_config->rx_endpoints; + get_ru_xml_list(buffer, "static-low-level-rx-endpoints", &rx_end->name, &rx_end->num); + AssertError(rx_end->name != NULL, return false, "[MPLANE] Cannot get RX endpoint names.\n"); + + // RX carriers + uplane_info_t *rx_carriers = &ru_mplane_config->rx_carriers; + get_ru_xml_list(buffer, "rx-arrays", &rx_carriers->name, &rx_carriers->num); + AssertError(rx_carriers->name != NULL, return false, "[MPLANE] Cannot get RX carrier names.\n"); + + MP_LOG_I("Successfully retrieved all the U-plane info - interface name, TX/RX carrier names, and TX/RX endpoint names.\n"); + + return true; +} diff --git a/radio/fhi_72/mplane/ru-mplane-api.h b/radio/fhi_72/mplane/ru-mplane-api.h index 5b49814efa..1afabd4d23 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.h +++ b/radio/fhi_72/mplane/ru-mplane-api.h @@ -94,4 +94,6 @@ typedef struct { 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); + #endif /* RU_MPLANE_API_H */ From dd8a6eaaf53a8210613714a9d53c697a17110f13 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 16:56:54 +0100 Subject: [PATCH 16/27] Load yang models Ideally, we should load the yang models from the RU operational datastore, but the issues are following: 1) the yang models order is not good - dependancy models have to be loaded first 2) earlier O-RAN yang versions (e.g. v4) is not properly defined (i.e. optional parameters should not be included by default) Added support in both cases, loading from RU with RPC, and loading statically from "radio/fhi_72/mplane/yang/models" folder. --- radio/fhi_72/mplane/CMakeLists.txt | 1 + radio/fhi_72/mplane/yang/get-yang.c | 141 + radio/fhi_72/mplane/yang/get-yang.h | 31 + .../mplane/yang/models/iana-hardware.yang | 180 ++ .../mplane/yang/models/iana-if-type.yang | 1611 ++++++++++ .../mplane/yang/models/ietf-hardware.yang | 1141 +++++++ .../mplane/yang/models/ietf-interfaces.yang | 1073 +++++++ radio/fhi_72/mplane/yang/models/ietf-ip.yang | 860 ++++++ .../models/o-ran-compression-factors.yang | 368 +++ .../mplane/yang/models/o-ran-interfaces.yang | 414 +++ .../mplane/yang/models/o-ran-module-cap.yang | 840 +++++ .../yang/models/o-ran-processing-element.yang | 362 +++ .../mplane/yang/models/o-ran-uplane-conf.yang | 2706 +++++++++++++++++ 13 files changed, 9728 insertions(+) create mode 100644 radio/fhi_72/mplane/yang/get-yang.c create mode 100644 radio/fhi_72/mplane/yang/get-yang.h create mode 100755 radio/fhi_72/mplane/yang/models/iana-hardware.yang create mode 100644 radio/fhi_72/mplane/yang/models/iana-if-type.yang create mode 100755 radio/fhi_72/mplane/yang/models/ietf-hardware.yang create mode 100644 radio/fhi_72/mplane/yang/models/ietf-interfaces.yang create mode 100644 radio/fhi_72/mplane/yang/models/ietf-ip.yang create mode 100644 radio/fhi_72/mplane/yang/models/o-ran-compression-factors.yang create mode 100644 radio/fhi_72/mplane/yang/models/o-ran-interfaces.yang create mode 100644 radio/fhi_72/mplane/yang/models/o-ran-module-cap.yang create mode 100644 radio/fhi_72/mplane/yang/models/o-ran-processing-element.yang create mode 100644 radio/fhi_72/mplane/yang/models/o-ran-uplane-conf.yang diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index f028be8102..183121e40a 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -32,6 +32,7 @@ target_sources(oran_fhlib_5g_mplane PRIVATE subscribe-mplane.c ru-mplane-api.c xml/get-xml.c + yang/get-yang.c ) pkg_check_modules(libyang REQUIRED libyang) diff --git a/radio/fhi_72/mplane/yang/get-yang.c b/radio/fhi_72/mplane/yang/get-yang.c new file mode 100644 index 0000000000..c27454136f --- /dev/null +++ b/radio/fhi_72/mplane/yang/get-yang.c @@ -0,0 +1,141 @@ +/* + * 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 "get-yang.h" +#include "../rpc-send-recv.h" +#include "common/utils/assertions.h" + +#include + +static bool store_schemas(xmlNode *node, ru_session_t *ru_session, struct ly_ctx **ctx) +{ + int timeout = CLI_RPC_REPLY_TIMEOUT; + NC_WD_MODE wd = NC_WD_ALL; + NC_PARAMTYPE param = NC_PARAMTYPE_CONST; + LYS_INFORMAT ly_format = LYS_IN_YANG; + +#ifdef MPLANE_V1 + *ctx = ly_ctx_new(NULL, 0); +#elif defined MPLANE_V2 + ly_ctx_new(NULL, 0, ctx); +#endif + + for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next) { + if (strcmp((const char *)cur_node->name, "schema") == 0) { + + xmlNode *name_node = xmlFirstElementChild(cur_node); + char *module_name = (char *)xmlNodeGetContent(name_node); + xmlNode *revision_node = xmlNextElementSibling(name_node); + char *module_revision = (char *)xmlNodeGetContent(revision_node); + xmlNode *format_node = xmlNextElementSibling(revision_node); + char *module_format = (char *)xmlNodeGetContent(format_node); + + if (strcmp(module_format, "yang") != 0) + 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); + 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 (schema_data) { +#ifdef MPLANE_V1 + const struct lys_module *mod = lys_parse_mem(*ctx, schema_data, ly_format); +#elif defined MPLANE_V2 + struct lys_module *mod = NULL; + lys_parse_mem(*ctx, schema_data, ly_format, &mod); +#endif + free(schema_data); + if (!mod) { + MP_LOG_W("Unable to load module \"%s\" from RU \"%s\".\n", module_name, ru_session->ru_ip_add); + nc_rpc_free(get_schema_rpc); + ly_ctx_destroy(*ctx); + return false; + } + } + nc_rpc_free(get_schema_rpc); + } + } + + return true; +} + +static bool load_from_operational_ds(xmlNode *node, ru_session_t *ru_session, struct ly_ctx **ctx) +{ + for (xmlNode *schemas_node = node; schemas_node; schemas_node = schemas_node->next) { + if(schemas_node->type != XML_ELEMENT_NODE) + continue; + if (strcmp((const char *)schemas_node->name, "schemas") == 0) { + return store_schemas(schemas_node->children, ru_session, ctx); + } else { + bool success = load_from_operational_ds(schemas_node->children, ru_session, ctx); + if (success) + return true; + } + } + return false; +} + +bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ctx **ctx) +{ + // Initialize the xml file + size_t len = strlen(buffer) + 1; + xmlDoc *doc = xmlReadMemory(buffer, len, NULL, NULL, 0); + xmlNode *root_element = xmlDocGetRootElement(doc); + + bool success = load_from_operational_ds(root_element->children, ru_session, ctx); + if (success) { + MP_LOG_I("Successfully loaded all yang modules from operational datastore for RU \"%s\".\n", ru_session->ru_ip_add); + return true; + } else { + MP_LOG_W("Unable to load all yang modules from operational datastore for RU \"%s\". Using yang models present in \"models\" subfolder.\n", ru_session->ru_ip_add); + } + + /* ideally, we should load the yang models from the operational datastore, but the issues are following: + 1) the yang models order is not good - the dependancy models have to be loaded first + 2) earlier O-RAN yang versions (e.g. v4) is not properly defined (i.e. optional parameters should not be included by default) */ + const char *yang_dir = YANG_MODELS; + const char *yang_models[] = {"ietf-interfaces", "iana-if-type", "ietf-ip", "iana-hardware", "ietf-hardware", "o-ran-interfaces", "o-ran-module-cap", "o-ran-compression-factors", "o-ran-processing-element", "o-ran-uplane-conf"}; + +#ifdef MPLANE_V1 + *ctx = ly_ctx_new(yang_dir, 0); + AssertError(*ctx != NULL, return false, "[MPLANE] Unable to create libyang context: %s.\n", ly_errmsg(*ctx)); +#elif defined MPLANE_V2 + LY_ERR ret = ly_ctx_new(yang_dir, 0, ctx); + AssertError(ret == LY_SUCCESS, return false, "[MPLANE] Unable to create libyang context: %s.\n", ly_errmsg(*ctx)); +#endif + + const size_t num_models = sizeof(yang_models) / sizeof(yang_models[0]); + for (size_t i = 0; i < num_models; ++i) { +#ifdef MPLANE_V1 + const struct lys_module *mod = ly_ctx_load_module(*ctx, yang_models[i], NULL); + AssertError(mod != NULL, return false, "[MPLANE] Failed to load yang model %s.\n", yang_models[i]); +#elif defined MPLANE_V2 + const struct lys_module *mod = ly_ctx_load_module(*ctx, yang_models[i], NULL, NULL); + AssertError(mod != NULL, return false, "[MPLANE] Failed to load yang model %s.\n", yang_models[i]); +#endif + } + + MP_LOG_I("Successfully loaded all yang modules for RU \"%s\".\n", ru_session->ru_ip_add); + + return true; +} diff --git a/radio/fhi_72/mplane/yang/get-yang.h b/radio/fhi_72/mplane/yang/get-yang.h new file mode 100644 index 0000000000..5956bde203 --- /dev/null +++ b/radio/fhi_72/mplane/yang/get-yang.h @@ -0,0 +1,31 @@ +/* + * 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 + */ + +#ifndef GET_MPLANE_YANG_MODELS_H +#define GET_MPLANE_YANG_MODELS_H + +#include "../ru-mplane-api.h" + +#include + +bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ctx **ctx); + +#endif /* GET_MPLANE_YANG_MODELS_H */ diff --git a/radio/fhi_72/mplane/yang/models/iana-hardware.yang b/radio/fhi_72/mplane/yang/models/iana-hardware.yang new file mode 100755 index 0000000000..52bcaf3a03 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/iana-hardware.yang @@ -0,0 +1,180 @@ +module iana-hardware { +yang-version 1.1; +namespace "urn:ietf:params:xml:ns:yang:iana-hardware"; +prefix ianahw; + +organization "IANA"; +contact + " Internet Assigned Numbers Authority + Postal: ICANN + 12025 Waterfront Drive, Suite 300 + Los Angeles, CA 90094-2536 + United States of America + Tel: +1 310 301 5800 + E-Mail: iana@iana.org>"; + +description + "IANA-defined identities for hardware class. + The latest revision of this YANG module can be obtained from + the IANA website. + Requests for new values should be made to IANA via + email (iana@iana.org). + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + The initial version of this YANG module is part of RFC 8348; + see the RFC itself for full legal notices."; +reference + "https://www.iana.org/assignments/yang-parameters"; + +revision 2018-03-13 { + description + "Initial revision."; + reference + "RFC 8348: A YANG Data Model for Hardware Management"; +} + +/* + * Identities + */ + +identity hardware-class { + description + "This identity is the base for all hardware class + identifiers."; +} + +identity unknown { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is unknown + to the server."; +} + +identity chassis { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is an + overall container for networking equipment. Any class of + physical component, except a stack, may be contained within a + chassis; a chassis may only be contained within a stack."; +} + +identity backplane { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of device for aggregating and forwarding networking traffic, + such as a shared backplane in a modular ethernet switch. Note + that an implementation may model a backplane as a single + physical component, which is actually implemented as multiple + discrete physical components (within a chassis or stack)."; +} + +identity container { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is capable + of containing one or more removable physical entities, + possibly of different types. For example, each (empty or + full) slot in a chassis will be modeled as a container. Note + that all removable physical components should be modeled + within a container component, such as field-replaceable + modules, fans, or power supplies. Note that all known + containers should be modeled by the agent, including empty + containers."; +} + +identity power-supply { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is a + power-supplying component."; +} + +identity fan { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is a fan or + other heat-reduction component."; +} + +identity sensor { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of sensor, such as a temperature sensor within a router + chassis."; +} + +identity module { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of self-contained sub-system. If a module component is + removable, then it should be modeled within a container + component; otherwise, it should be modeled directly within + another physical component (e.g., a chassis or another + module)."; +} + +identity port { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of networking port capable of receiving and/or transmitting + networking traffic."; +} + +identity stack { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of super-container (possibly virtual) intended to group + together multiple chassis entities. A stack may be realized + by a virtual cable, a real interconnect cable attached to + multiple chassis, or multiple interconnect cables. A stack + should not be modeled within any other physical components, + but a stack may be contained within another stack. Only + chassis components should be contained within a stack."; +} + +identity cpu { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of central processing unit."; +} + +identity energy-object { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of energy object, i.e., it is a piece of equipment that is + part of or attached to a communications network that is + monitored, it is controlled, or it aids in the management of + another device for Energy Management."; +} + +identity battery { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of battery."; +} + +identity storage-drive { + base ianahw:hardware-class; + description + "This identity is applicable if the hardware class is some sort + of component with data storage capability as its main + functionality, e.g., hard disk drive (HDD), solid-state device + (SSD), solid-state hybrid drive (SSHD), object storage device + (OSD), or other."; +} +} diff --git a/radio/fhi_72/mplane/yang/models/iana-if-type.yang b/radio/fhi_72/mplane/yang/models/iana-if-type.yang new file mode 100644 index 0000000000..24d04e60fe --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/iana-if-type.yang @@ -0,0 +1,1611 @@ +module iana-if-type { + namespace "urn:ietf:params:xml:ns:yang:iana-if-type"; + prefix ianaift; + + import ietf-interfaces { + prefix if; + } + + organization "IANA"; + contact + " Internet Assigned Numbers Authority + Postal: ICANN + 12025 Waterfront Drive, Suite 300 + Los Angeles, CA 90094-2536 + United States + Tel: +1 310 301 5800 + "; + description + "This YANG module defines YANG identities for IANA-registered + interface types. + This YANG module is maintained by IANA and reflects the + 'ifType definitions' registry. + The latest revision of this YANG module can be obtained from + the IANA web site. + Requests for new values should be made to IANA via + email (iana&iana.org). + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + The initial version of this YANG module is part of RFC 7224; + see the RFC itself for full legal notices."; + reference + "IANA 'ifType definitions' registry. + "; + + revision 2017-01-19 { + description + "Registered ifType 289."; + } + + revision 2016-11-23 { + description + "Registered ifTypes 283-288."; + } + + revision 2016-06-09 { + description + "Registered ifType 282."; + } + revision 2016-05-03 { + description + "Registered ifType 281."; + } + revision 2015-06-12 { + description + "Corrected formatting issue."; + } + revision 2014-09-24 { + description + "Registered ifType 280."; + } + revision 2014-09-19 { + description + "Registered ifType 279."; + } + revision 2014-07-03 { + description + "Registered ifTypes 277-278."; + } + revision 2014-05-19 { + description + "Updated the contact address."; + } + revision 2014-05-08 { + description + "Initial revision."; + reference + "RFC 7224: IANA Interface Type YANG Module"; + } + + identity iana-interface-type { + base if:interface-type; + description + "This identity is used as a base for all interface types + defined in the 'ifType definitions' registry."; + } + + identity other { + base iana-interface-type; + } + identity regular1822 { + base iana-interface-type; + } + identity hdh1822 { + base iana-interface-type; + } + identity ddnX25 { + base iana-interface-type; + } + identity rfc877x25 { + base iana-interface-type; + reference + "RFC 1382 - SNMP MIB Extension for the X.25 Packet Layer"; + } + identity ethernetCsmacd { + base iana-interface-type; + description + "For all Ethernet-like interfaces, regardless of speed, + as per RFC 3635."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity iso88023Csmacd { + base iana-interface-type; + status deprecated; + description + "Deprecated via RFC 3635. + Use ethernetCsmacd(6) instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity iso88024TokenBus { + base iana-interface-type; + } + identity iso88025TokenRing { + base iana-interface-type; + } + identity iso88026Man { + base iana-interface-type; + } + identity starLan { + base iana-interface-type; + status deprecated; + description + "Deprecated via RFC 3635. + Use ethernetCsmacd(6) instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity proteon10Mbit { + base iana-interface-type; + } + identity proteon80Mbit { + base iana-interface-type; + } + identity hyperchannel { + base iana-interface-type; + } + identity fddi { + base iana-interface-type; + reference + "RFC 1512 - FDDI Management Information Base"; + } + identity lapb { + base iana-interface-type; + reference + "RFC 1381 - SNMP MIB Extension for X.25 LAPB"; + } + identity sdlc { + base iana-interface-type; + } + identity ds1 { + base iana-interface-type; + description + "DS1-MIB."; + reference + "RFC 4805 - Definitions of Managed Objects for the + DS1, J1, E1, DS2, and E2 Interface Types"; + } + identity e1 { + base iana-interface-type; + status obsolete; + description + "Obsolete; see DS1-MIB."; + reference + "RFC 4805 - Definitions of Managed Objects for the + DS1, J1, E1, DS2, and E2 Interface Types"; + } + identity basicISDN { + base iana-interface-type; + description + "No longer used. See also RFC 2127."; + } + identity primaryISDN { + base iana-interface-type; + description + "No longer used. See also RFC 2127."; + } + identity propPointToPointSerial { + base iana-interface-type; + description + "Proprietary serial."; + } + identity ppp { + base iana-interface-type; + } + identity softwareLoopback { + base iana-interface-type; + } + identity eon { + base iana-interface-type; + description + "CLNP over IP."; + } + identity ethernet3Mbit { + base iana-interface-type; + } + identity nsip { + base iana-interface-type; + description + "XNS over IP."; + } + identity slip { + base iana-interface-type; + description + "Generic SLIP."; + } + identity ultra { + base iana-interface-type; + description + "Ultra Technologies."; + } + identity ds3 { + base iana-interface-type; + description + "DS3-MIB."; + reference + "RFC 3896 - Definitions of Managed Objects for the + DS3/E3 Interface Type"; + } + identity sip { + base iana-interface-type; + description + "SMDS, coffee."; + reference + "RFC 1694 - Definitions of Managed Objects for SMDS + Interfaces using SMIv2"; + } + identity frameRelay { + base iana-interface-type; + description + "DTE only."; + reference + "RFC 2115 - Management Information Base for Frame Relay + DTEs Using SMIv2"; + } + identity rs232 { + base iana-interface-type; + reference + "RFC 1659 - Definitions of Managed Objects for RS-232-like + Hardware Devices using SMIv2"; + } + identity para { + base iana-interface-type; + description + "Parallel-port."; + reference + "RFC 1660 - Definitions of Managed Objects for + Parallel-printer-like Hardware Devices using + SMIv2"; + } + identity arcnet { + base iana-interface-type; + description + "ARCnet."; + } + identity arcnetPlus { + base iana-interface-type; + description + "ARCnet Plus."; + } + identity atm { + base iana-interface-type; + description + "ATM cells."; + } + identity miox25 { + base iana-interface-type; + reference + "RFC 1461 - SNMP MIB extension for Multiprotocol + Interconnect over X.25"; + } + identity sonet { + base iana-interface-type; + description + "SONET or SDH."; + } + identity x25ple { + base iana-interface-type; + reference + "RFC 2127 - ISDN Management Information Base using SMIv2"; + } + identity iso88022llc { + base iana-interface-type; + } + identity localTalk { + base iana-interface-type; + } + identity smdsDxi { + base iana-interface-type; + } + identity frameRelayService { + base iana-interface-type; + description + "FRNETSERV-MIB."; + reference + "RFC 2954 - Definitions of Managed Objects for Frame + Relay Service"; + } + identity v35 { + base iana-interface-type; + } + identity hssi { + base iana-interface-type; + } + identity hippi { + base iana-interface-type; + } + identity modem { + base iana-interface-type; + description + "Generic modem."; + } + identity aal5 { + base iana-interface-type; + description + "AAL5 over ATM."; + } + identity sonetPath { + base iana-interface-type; + } + identity sonetVT { + base iana-interface-type; + } + identity smdsIcip { + base iana-interface-type; + description + "SMDS InterCarrier Interface."; + } + identity propVirtual { + base iana-interface-type; + description + "Proprietary virtual/internal."; + reference + "RFC 2863 - The Interfaces Group MIB"; + } + identity propMultiplexor { + base iana-interface-type; + description + "Proprietary multiplexing."; + reference + "RFC 2863 - The Interfaces Group MIB"; + } + identity ieee80212 { + base iana-interface-type; + description + "100BaseVG."; + } + identity fibreChannel { + base iana-interface-type; + description + "Fibre Channel."; + } + identity hippiInterface { + base iana-interface-type; + description + "HIPPI interfaces."; + } + identity frameRelayInterconnect { + base iana-interface-type; + status obsolete; + description + "Obsolete; use either + frameRelay(32) or frameRelayService(44)."; + } + identity aflane8023 { + base iana-interface-type; + description + "ATM Emulated LAN for 802.3."; + } + identity aflane8025 { + base iana-interface-type; + description + "ATM Emulated LAN for 802.5."; + } + identity cctEmul { + base iana-interface-type; + description + "ATM Emulated circuit."; + } + identity fastEther { + base iana-interface-type; + status deprecated; + description + "Obsoleted via RFC 3635. + ethernetCsmacd(6) should be used instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity isdn { + base iana-interface-type; + description + "ISDN and X.25."; + reference + "RFC 1356 - Multiprotocol Interconnect on X.25 and ISDN + in the Packet Mode"; + } + identity v11 { + base iana-interface-type; + description + "CCITT V.11/X.21."; + } + identity v36 { + base iana-interface-type; + description + "CCITT V.36."; + } + identity g703at64k { + base iana-interface-type; + description + "CCITT G703 at 64Kbps."; + } + identity g703at2mb { + base iana-interface-type; + status obsolete; + description + "Obsolete; see DS1-MIB."; + } + identity qllc { + base iana-interface-type; + description + "SNA QLLC."; + } + identity fastEtherFX { + base iana-interface-type; + status deprecated; + description + "Obsoleted via RFC 3635. + ethernetCsmacd(6) should be used instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity channel { + base iana-interface-type; + description + "Channel."; + } + identity ieee80211 { + base iana-interface-type; + description + "Radio spread spectrum."; + } + identity ibm370parChan { + base iana-interface-type; + description + "IBM System 360/370 OEMI Channel."; + } + identity escon { + base iana-interface-type; + description + "IBM Enterprise Systems Connection."; + } + identity dlsw { + base iana-interface-type; + description + "Data Link Switching."; + } + identity isdns { + base iana-interface-type; + description + "ISDN S/T interface."; + } + identity isdnu { + base iana-interface-type; + description + "ISDN U interface."; + } + identity lapd { + base iana-interface-type; + description + "Link Access Protocol D."; + } + identity ipSwitch { + base iana-interface-type; + description + "IP Switching Objects."; + } + identity rsrb { + base iana-interface-type; + description + "Remote Source Route Bridging."; + } + identity atmLogical { + base iana-interface-type; + description + "ATM Logical Port."; + reference + "RFC 3606 - Definitions of Supplemental Managed Objects + for ATM Interface"; + } + identity ds0 { + base iana-interface-type; + description + "Digital Signal Level 0."; + reference + "RFC 2494 - Definitions of Managed Objects for the DS0 + and DS0 Bundle Interface Type"; + } + identity ds0Bundle { + base iana-interface-type; + description + "Group of ds0s on the same ds1."; + reference + "RFC 2494 - Definitions of Managed Objects for the DS0 + and DS0 Bundle Interface Type"; + } + identity bsc { + base iana-interface-type; + description + "Bisynchronous Protocol."; + } + identity async { + base iana-interface-type; + description + "Asynchronous Protocol."; + } + identity cnr { + base iana-interface-type; + description + "Combat Net Radio."; + } + identity iso88025Dtr { + base iana-interface-type; + description + "ISO 802.5r DTR."; + } + identity eplrs { + base iana-interface-type; + description + "Ext Pos Loc Report Sys."; + } + identity arap { + base iana-interface-type; + description + "Appletalk Remote Access Protocol."; + } + identity propCnls { + base iana-interface-type; + description + "Proprietary Connectionless Protocol."; + } + identity hostPad { + base iana-interface-type; + description + "CCITT-ITU X.29 PAD Protocol."; + } + identity termPad { + base iana-interface-type; + description + "CCITT-ITU X.3 PAD Facility."; + } + identity frameRelayMPI { + base iana-interface-type; + description + "Multiproto Interconnect over FR."; + } + identity x213 { + base iana-interface-type; + description + "CCITT-ITU X213."; + } + identity adsl { + base iana-interface-type; + description + "Asymmetric Digital Subscriber Loop."; + } + identity radsl { + base iana-interface-type; + description + "Rate-Adapt. Digital Subscriber Loop."; + } + identity sdsl { + base iana-interface-type; + description + "Symmetric Digital Subscriber Loop."; + } + identity vdsl { + base iana-interface-type; + description + "Very H-Speed Digital Subscrib. Loop."; + } + identity iso88025CRFPInt { + base iana-interface-type; + description + "ISO 802.5 CRFP."; + } + identity myrinet { + base iana-interface-type; + description + "Myricom Myrinet."; + } + identity voiceEM { + base iana-interface-type; + description + "Voice recEive and transMit."; + } + identity voiceFXO { + base iana-interface-type; + description + "Voice Foreign Exchange Office."; + } + identity voiceFXS { + base iana-interface-type; + description + "Voice Foreign Exchange Station."; + } + identity voiceEncap { + base iana-interface-type; + description + "Voice encapsulation."; + } + identity voiceOverIp { + base iana-interface-type; + description + "Voice over IP encapsulation."; + } + identity atmDxi { + base iana-interface-type; + description + "ATM DXI."; + } + identity atmFuni { + base iana-interface-type; + description + "ATM FUNI."; + } + identity atmIma { + base iana-interface-type; + description + "ATM IMA."; + } + identity pppMultilinkBundle { + base iana-interface-type; + description + "PPP Multilink Bundle."; + } + identity ipOverCdlc { + base iana-interface-type; + description + "IBM ipOverCdlc."; + } + identity ipOverClaw { + base iana-interface-type; + description + "IBM Common Link Access to Workstn."; + } + identity stackToStack { + base iana-interface-type; + description + "IBM stackToStack."; + } + identity virtualIpAddress { + base iana-interface-type; + description + "IBM VIPA."; + } + identity mpc { + base iana-interface-type; + description + "IBM multi-protocol channel support."; + } + identity ipOverAtm { + base iana-interface-type; + description + "IBM ipOverAtm."; + reference + "RFC 2320 - Definitions of Managed Objects for Classical IP + and ARP Over ATM Using SMIv2 (IPOA-MIB)"; + } + identity iso88025Fiber { + base iana-interface-type; + description + "ISO 802.5j Fiber Token Ring."; + } + identity tdlc { + base iana-interface-type; + description + "IBM twinaxial data link control."; + } + identity gigabitEthernet { + base iana-interface-type; + status deprecated; + description + "Obsoleted via RFC 3635. + ethernetCsmacd(6) should be used instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity hdlc { + base iana-interface-type; + description + "HDLC."; + } + identity lapf { + base iana-interface-type; + description + "LAP F."; + } + identity v37 { + base iana-interface-type; + description + "V.37."; + } + identity x25mlp { + base iana-interface-type; + description + "Multi-Link Protocol."; + } + identity x25huntGroup { + base iana-interface-type; + description + "X25 Hunt Group."; + } + identity transpHdlc { + base iana-interface-type; + description + "Transp HDLC."; + } + identity interleave { + base iana-interface-type; + description + "Interleave channel."; + } + identity fast { + base iana-interface-type; + description + "Fast channel."; + } + identity ip { + base iana-interface-type; + description + "IP (for APPN HPR in IP networks)."; + } + identity docsCableMaclayer { + base iana-interface-type; + description + "CATV Mac Layer."; + } + identity docsCableDownstream { + base iana-interface-type; + description + "CATV Downstream interface."; + } + identity docsCableUpstream { + base iana-interface-type; + description + "CATV Upstream interface."; + } + identity a12MppSwitch { + base iana-interface-type; + description + "Avalon Parallel Processor."; + } + identity tunnel { + base iana-interface-type; + description + "Encapsulation interface."; + } + identity coffee { + base iana-interface-type; + description + "Coffee pot."; + reference + "RFC 2325 - Coffee MIB"; + } + identity ces { + base iana-interface-type; + description + "Circuit Emulation Service."; + } + identity atmSubInterface { + base iana-interface-type; + description + "ATM Sub Interface."; + } + identity l2vlan { + base iana-interface-type; + description + "Layer 2 Virtual LAN using 802.1Q."; + } + identity l3ipvlan { + base iana-interface-type; + description + "Layer 3 Virtual LAN using IP."; + } + identity l3ipxvlan { + base iana-interface-type; + description + "Layer 3 Virtual LAN using IPX."; + } + identity digitalPowerline { + base iana-interface-type; + description + "IP over Power Lines."; + } + identity mediaMailOverIp { + base iana-interface-type; + description + "Multimedia Mail over IP."; + } + identity dtm { + base iana-interface-type; + description + "Dynamic synchronous Transfer Mode."; + } + identity dcn { + base iana-interface-type; + description + "Data Communications Network."; + } + identity ipForward { + base iana-interface-type; + description + "IP Forwarding Interface."; + } + identity msdsl { + base iana-interface-type; + description + "Multi-rate Symmetric DSL."; + } + identity ieee1394 { + base iana-interface-type; + + description + "IEEE1394 High Performance Serial Bus."; + } + identity if-gsn { + base iana-interface-type; + description + "HIPPI-6400."; + } + identity dvbRccMacLayer { + base iana-interface-type; + description + "DVB-RCC MAC Layer."; + } + identity dvbRccDownstream { + base iana-interface-type; + description + "DVB-RCC Downstream Channel."; + } + identity dvbRccUpstream { + base iana-interface-type; + description + "DVB-RCC Upstream Channel."; + } + identity atmVirtual { + base iana-interface-type; + description + "ATM Virtual Interface."; + } + identity mplsTunnel { + base iana-interface-type; + description + "MPLS Tunnel Virtual Interface."; + } + identity srp { + base iana-interface-type; + description + "Spatial Reuse Protocol."; + } + identity voiceOverAtm { + base iana-interface-type; + description + "Voice over ATM."; + } + identity voiceOverFrameRelay { + base iana-interface-type; + description + "Voice Over Frame Relay."; + } + identity idsl { + base iana-interface-type; + description + "Digital Subscriber Loop over ISDN."; + } + identity compositeLink { + base iana-interface-type; + description + "Avici Composite Link Interface."; + } + identity ss7SigLink { + base iana-interface-type; + description + "SS7 Signaling Link."; + } + identity propWirelessP2P { + base iana-interface-type; + description + "Prop. P2P wireless interface."; + } + identity frForward { + base iana-interface-type; + description + "Frame Forward Interface."; + } + identity rfc1483 { + base iana-interface-type; + description + "Multiprotocol over ATM AAL5."; + reference + "RFC 1483 - Multiprotocol Encapsulation over ATM + Adaptation Layer 5"; + } + identity usb { + base iana-interface-type; + description + "USB Interface."; + } + identity ieee8023adLag { + base iana-interface-type; + description + "IEEE 802.3ad Link Aggregate."; + } + identity bgppolicyaccounting { + base iana-interface-type; + description + "BGP Policy Accounting."; + } + identity frf16MfrBundle { + base iana-interface-type; + description + "FRF.16 Multilink Frame Relay."; + } + identity h323Gatekeeper { + base iana-interface-type; + description + "H323 Gatekeeper."; + } + identity h323Proxy { + base iana-interface-type; + description + "H323 Voice and Video Proxy."; + } + identity mpls { + base iana-interface-type; + description + "MPLS."; + } + identity mfSigLink { + base iana-interface-type; + description + "Multi-frequency signaling link."; + } + identity hdsl2 { + base iana-interface-type; + description + "High Bit-Rate DSL - 2nd generation."; + } + identity shdsl { + base iana-interface-type; + description + "Multirate HDSL2."; + } + identity ds1FDL { + base iana-interface-type; + description + "Facility Data Link (4Kbps) on a DS1."; + } + identity pos { + base iana-interface-type; + description + "Packet over SONET/SDH Interface."; + } + identity dvbAsiIn { + base iana-interface-type; + description + "DVB-ASI Input."; + } + identity dvbAsiOut { + base iana-interface-type; + description + "DVB-ASI Output."; + } + identity plc { + base iana-interface-type; + description + "Power Line Communications."; + } + identity nfas { + base iana-interface-type; + description + "Non-Facility Associated Signaling."; + } + identity tr008 { + base iana-interface-type; + description + "TR008."; + } + identity gr303RDT { + base iana-interface-type; + description + "Remote Digital Terminal."; + } + identity gr303IDT { + base iana-interface-type; + description + "Integrated Digital Terminal."; + } + identity isup { + base iana-interface-type; + description + "ISUP."; + } + identity propDocsWirelessMaclayer { + base iana-interface-type; + description + "Cisco proprietary Maclayer."; + } + identity propDocsWirelessDownstream { + base iana-interface-type; + description + "Cisco proprietary Downstream."; + } + identity propDocsWirelessUpstream { + base iana-interface-type; + description + "Cisco proprietary Upstream."; + } + identity hiperlan2 { + base iana-interface-type; + description + "HIPERLAN Type 2 Radio Interface."; + } + identity propBWAp2Mp { + base iana-interface-type; + description + "PropBroadbandWirelessAccesspt2Multipt (use of this value + for IEEE 802.16 WMAN interfaces as per IEEE Std 802.16f + is deprecated, and ieee80216WMAN(237) should be used + instead)."; + } + identity sonetOverheadChannel { + base iana-interface-type; + description + "SONET Overhead Channel."; + } + identity digitalWrapperOverheadChannel { + base iana-interface-type; + description + "Digital Wrapper."; + } + identity aal2 { + base iana-interface-type; + description + "ATM adaptation layer 2."; + } + identity radioMAC { + base iana-interface-type; + description + "MAC layer over radio links."; + } + identity atmRadio { + base iana-interface-type; + description + "ATM over radio links."; + } + identity imt { + base iana-interface-type; + description + "Inter-Machine Trunks."; + } + identity mvl { + base iana-interface-type; + description + "Multiple Virtual Lines DSL."; + } + identity reachDSL { + base iana-interface-type; + description + "Long Reach DSL."; + } + identity frDlciEndPt { + base iana-interface-type; + description + "Frame Relay DLCI End Point."; + } + identity atmVciEndPt { + base iana-interface-type; + description + "ATM VCI End Point."; + } + identity opticalChannel { + base iana-interface-type; + description + "Optical Channel."; + } + identity opticalTransport { + base iana-interface-type; + description + "Optical Transport."; + } + identity propAtm { + base iana-interface-type; + description + "Proprietary ATM."; + } + identity voiceOverCable { + base iana-interface-type; + description + "Voice Over Cable Interface."; + } + identity infiniband { + base iana-interface-type; + description + "Infiniband."; + } + identity teLink { + base iana-interface-type; + description + "TE Link."; + } + identity q2931 { + base iana-interface-type; + description + "Q.2931."; + } + identity virtualTg { + base iana-interface-type; + description + "Virtual Trunk Group."; + } + identity sipTg { + base iana-interface-type; + description + "SIP Trunk Group."; + } + identity sipSig { + base iana-interface-type; + description + "SIP Signaling."; + } + identity docsCableUpstreamChannel { + base iana-interface-type; + description + "CATV Upstream Channel."; + } + identity econet { + base iana-interface-type; + description + "Acorn Econet."; + } + identity pon155 { + base iana-interface-type; + description + "FSAN 155Mb Symetrical PON interface."; + } + identity pon622 { + base iana-interface-type; + description + "FSAN 622Mb Symetrical PON interface."; + } + identity bridge { + base iana-interface-type; + description + "Transparent bridge interface."; + } + identity linegroup { + base iana-interface-type; + description + "Interface common to multiple lines."; + } + identity voiceEMFGD { + base iana-interface-type; + description + "Voice E&M Feature Group D."; + } + identity voiceFGDEANA { + base iana-interface-type; + description + "Voice FGD Exchange Access North American."; + } + identity voiceDID { + base iana-interface-type; + description + "Voice Direct Inward Dialing."; + } + identity mpegTransport { + base iana-interface-type; + description + "MPEG transport interface."; + } + identity sixToFour { + base iana-interface-type; + status deprecated; + description + "6to4 interface (DEPRECATED)."; + reference + "RFC 4087 - IP Tunnel MIB"; + } + identity gtp { + base iana-interface-type; + description + "GTP (GPRS Tunneling Protocol)."; + } + identity pdnEtherLoop1 { + base iana-interface-type; + description + "Paradyne EtherLoop 1."; + } + identity pdnEtherLoop2 { + base iana-interface-type; + description + "Paradyne EtherLoop 2."; + } + identity opticalChannelGroup { + base iana-interface-type; + description + "Optical Channel Group."; + } + identity homepna { + base iana-interface-type; + description + "HomePNA ITU-T G.989."; + } + identity gfp { + base iana-interface-type; + description + "Generic Framing Procedure (GFP)."; + } + identity ciscoISLvlan { + base iana-interface-type; + description + "Layer 2 Virtual LAN using Cisco ISL."; + } + identity actelisMetaLOOP { + base iana-interface-type; + description + "Acteleis proprietary MetaLOOP High Speed Link."; + } + identity fcipLink { + base iana-interface-type; + description + "FCIP Link."; + } + identity rpr { + base iana-interface-type; + description + "Resilient Packet Ring Interface Type."; + } + identity qam { + base iana-interface-type; + description + "RF Qam Interface."; + } + identity lmp { + base iana-interface-type; + description + "Link Management Protocol."; + reference + "RFC 4327 - Link Management Protocol (LMP) Management + Information Base (MIB)"; + } + identity cblVectaStar { + base iana-interface-type; + description + "Cambridge Broadband Networks Limited VectaStar."; + } + identity docsCableMCmtsDownstream { + base iana-interface-type; + description + "CATV Modular CMTS Downstream Interface."; + } + identity adsl2 { + base iana-interface-type; + status deprecated; + description + "Asymmetric Digital Subscriber Loop Version 2 + (DEPRECATED/OBSOLETED - please use adsl2plus(238) + instead)."; + reference + "RFC 4706 - Definitions of Managed Objects for Asymmetric + Digital Subscriber Line 2 (ADSL2)"; + } + identity macSecControlledIF { + base iana-interface-type; + description + "MACSecControlled."; + } + identity macSecUncontrolledIF { + base iana-interface-type; + description + "MACSecUncontrolled."; + } + identity aviciOpticalEther { + base iana-interface-type; + description + "Avici Optical Ethernet Aggregate."; + } + identity atmbond { + base iana-interface-type; + description + "atmbond."; + } + identity voiceFGDOS { + base iana-interface-type; + description + "Voice FGD Operator Services."; + } + identity mocaVersion1 { + base iana-interface-type; + description + "MultiMedia over Coax Alliance (MoCA) Interface + as documented in information provided privately to IANA."; + } + identity ieee80216WMAN { + base iana-interface-type; + description + "IEEE 802.16 WMAN interface."; + } + identity adsl2plus { + base iana-interface-type; + description + "Asymmetric Digital Subscriber Loop Version 2 - + Version 2 Plus and all variants."; + } + identity dvbRcsMacLayer { + base iana-interface-type; + description + "DVB-RCS MAC Layer."; + reference + "RFC 5728 - The SatLabs Group DVB-RCS MIB"; + } + identity dvbTdm { + base iana-interface-type; + description + "DVB Satellite TDM."; + reference + "RFC 5728 - The SatLabs Group DVB-RCS MIB"; + } + identity dvbRcsTdma { + base iana-interface-type; + description + "DVB-RCS TDMA."; + reference + "RFC 5728 - The SatLabs Group DVB-RCS MIB"; + } + identity x86Laps { + base iana-interface-type; + description + "LAPS based on ITU-T X.86/Y.1323."; + } + identity wwanPP { + base iana-interface-type; + description + "3GPP WWAN."; + } + identity wwanPP2 { + base iana-interface-type; + description + "3GPP2 WWAN."; + } + identity voiceEBS { + base iana-interface-type; + description + "Voice P-phone EBS physical interface."; + } + identity ifPwType { + base iana-interface-type; + description + "Pseudowire interface type."; + reference + "RFC 5601 - Pseudowire (PW) Management Information Base (MIB)"; + } + identity ilan { + base iana-interface-type; + description + "Internal LAN on a bridge per IEEE 802.1ap."; + } + identity pip { + base iana-interface-type; + description + "Provider Instance Port on a bridge per IEEE 802.1ah PBB."; + } + identity aluELP { + base iana-interface-type; + description + "Alcatel-Lucent Ethernet Link Protection."; + } + identity gpon { + base iana-interface-type; + description + "Gigabit-capable passive optical networks (G-PON) as per + ITU-T G.948."; + } + identity vdsl2 { + base iana-interface-type; + description + "Very high speed digital subscriber line Version 2 + (as per ITU-T Recommendation G.993.2)."; + reference + "RFC 5650 - Definitions of Managed Objects for Very High + Speed Digital Subscriber Line 2 (VDSL2)"; + } + identity capwapDot11Profile { + base iana-interface-type; + description + "WLAN Profile Interface."; + reference + "RFC 5834 - Control and Provisioning of Wireless Access + Points (CAPWAP) Protocol Binding MIB for + IEEE 802.11"; + } + identity capwapDot11Bss { + base iana-interface-type; + description + "WLAN BSS Interface."; + reference + "RFC 5834 - Control and Provisioning of Wireless Access + Points (CAPWAP) Protocol Binding MIB for + IEEE 802.11"; + } + identity capwapWtpVirtualRadio { + base iana-interface-type; + description + "WTP Virtual Radio Interface."; + reference + "RFC 5833 - Control and Provisioning of Wireless Access + Points (CAPWAP) Protocol Base MIB"; + } + identity bits { + base iana-interface-type; + description + "bitsport."; + } + identity docsCableUpstreamRfPort { + base iana-interface-type; + description + "DOCSIS CATV Upstream RF Port."; + } + identity cableDownstreamRfPort { + base iana-interface-type; + description + "CATV downstream RF Port."; + } + identity vmwareVirtualNic { + base iana-interface-type; + description + "VMware Virtual Network Interface."; + } + identity ieee802154 { + base iana-interface-type; + description + "IEEE 802.15.4 WPAN interface."; + reference + "IEEE 802.15.4-2006"; + } + identity otnOdu { + base iana-interface-type; + description + "OTN Optical Data Unit."; + } + identity otnOtu { + base iana-interface-type; + description + "OTN Optical channel Transport Unit."; + } + identity ifVfiType { + base iana-interface-type; + description + "VPLS Forwarding Instance Interface Type."; + } + identity g9981 { + base iana-interface-type; + description + "G.998.1 bonded interface."; + } + identity g9982 { + base iana-interface-type; + description + "G.998.2 bonded interface."; + } + identity g9983 { + base iana-interface-type; + description + "G.998.3 bonded interface."; + } + + identity aluEpon { + base iana-interface-type; + description + "Ethernet Passive Optical Networks (E-PON)."; + } + identity aluEponOnu { + base iana-interface-type; + description + "EPON Optical Network Unit."; + } + identity aluEponPhysicalUni { + base iana-interface-type; + description + "EPON physical User to Network interface."; + } + identity aluEponLogicalLink { + base iana-interface-type; + description + "The emulation of a point-to-point link over the EPON + layer."; + } + identity aluGponOnu { + base iana-interface-type; + description + "GPON Optical Network Unit."; + reference + "ITU-T G.984.2"; + } + identity aluGponPhysicalUni { + base iana-interface-type; + description + "GPON physical User to Network interface."; + reference + "ITU-T G.984.2"; + } + identity vmwareNicTeam { + base iana-interface-type; + description + "VMware NIC Team."; + } + identity docsOfdmDownstream { + base iana-interface-type; + description + "CATV Downstream OFDM interface."; + } + identity docsOfdmaUpstream { + base iana-interface-type; + description + "CATV Upstream OFDMA interface."; + } + identity gfast { + base iana-interface-type; + description + "G.fast port."; + reference + "ITU-T G.9701"; + } + identity sdci { + base iana-interface-type; + description + "SDCI (IO-Link)."; + reference + "IEC 61131-9 Edition 1.0 2013-09"; + } + identity xboxWireless { + base iana-interface-type; + description + "Xbox wireless."; + } + identity fastdsl { + base iana-interface-type; + description + "FastDSL."; + reference + "BBF TR-355"; + } + identity docsCableScte55d1FwdOob { + base iana-interface-type; + description + "Cable SCTE 55-1 OOB Forward Channel."; + } + identity docsCableScte55d1RetOob { + base iana-interface-type; + description + "Cable SCTE 55-1 OOB Return Channel."; + } + identity docsCableScte55d2DsOob { + base iana-interface-type; + description + "Cable SCTE 55-2 OOB Downstream Channel."; + } + identity docsCableScte55d2UsOob { + base iana-interface-type; + description + "Cable SCTE 55-2 OOB Upstream Channel."; + } + identity docsCableNdf { + base iana-interface-type; + description + "Cable Narrowband Digital Forward."; + } + identity docsCableNdr { + base iana-interface-type; + description + "Cable Narrowband Digital Return."; + } + identity ptm { + base iana-interface-type; + description + "Packet Transfer Mode."; + } +} diff --git a/radio/fhi_72/mplane/yang/models/ietf-hardware.yang b/radio/fhi_72/mplane/yang/models/ietf-hardware.yang new file mode 100755 index 0000000000..f444e26ee6 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/ietf-hardware.yang @@ -0,0 +1,1141 @@ +module ietf-hardware { +yang-version 1.1; +namespace "urn:ietf:params:xml:ns:yang:ietf-hardware"; +prefix hw; + +import ietf-inet-types { + prefix inet; +} +import ietf-yang-types { + prefix yang; +} +import iana-hardware { + prefix ianahw; +} + +organization + "IETF NETMOD (Network Modeling) Working Group"; + +contact + "WG Web: + WG List: + Editor: Andy Bierman + + Editor: Martin Bjorklund + + Editor: Jie Dong + + Editor: Dan Romascanu + "; + +description + "This module contains a collection of YANG definitions for + managing hardware. + This data model is designed for the Network Management Datastore + Architecture (NMDA) defined in RFC 8342. + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 8348; see + the RFC itself for full legal notices."; + +revision 2018-03-13 { + description + "Initial revision."; + reference + "RFC 8348: A YANG Data Model for Hardware Management"; +} + +/* + * Features + */ + +feature entity-mib { + description + "This feature indicates that the device implements + the ENTITY-MIB."; + reference + "RFC 6933: Entity MIB (Version 4)"; +} + +feature hardware-state { + description + "Indicates that ENTITY-STATE-MIB objects are supported"; + reference + "RFC 4268: Entity State MIB"; +} + +feature hardware-sensor { + description + "Indicates that ENTITY-SENSOR-MIB objects are supported"; + reference + "RFC 3433: Entity Sensor Management Information Base"; +} + +/* + * Typedefs + */ + +typedef admin-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report administrative state."; + } + enum locked { + value 2; + description + "The resource is administratively prohibited from use."; + } + enum shutting-down { + value 3; + description + "The resource usage is administratively limited to current + instances of use."; + } + enum unlocked { + value 4; + description + "The resource is not administratively prohibited from + use."; + } + } + description + "Represents the various possible administrative states."; + reference + "RFC 4268: Entity State MIB - EntityAdminState"; +} + +typedef oper-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report its operational state."; + } + enum disabled { + value 2; + description + "The resource is totally inoperable."; + } + enum enabled { + value 3; + + description + "The resource is partially or fully operable."; + } + enum testing { + value 4; + description + "The resource is currently being tested and cannot + therefore report whether or not it is operational."; + } + } + description + "Represents the possible values of operational states."; + reference + "RFC 4268: Entity State MIB - EntityOperState"; +} + +typedef usage-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report usage state."; + } + enum idle { + value 2; + description + "The resource is servicing no users."; + } + enum active { + value 3; + description + "The resource is currently in use, and it has sufficient + spare capacity to provide for additional users."; + } + enum busy { + value 4; + description + "The resource is currently in use, but it currently has no + spare capacity to provide for additional users."; + } + } + description + "Represents the possible values of usage states."; + reference + "RFC 4268: Entity State MIB - EntityUsageState"; +} + +typedef alarm-state { + type bits { + bit unknown { + position 0; + description + "The resource is unable to report alarm state."; + } + bit under-repair { + position 1; + description + "The resource is currently being repaired, which, depending + on the implementation, may make the other values in this + bit string not meaningful."; + } + bit critical { + position 2; + description + "One or more critical alarms are active against the + resource."; + } + bit major { + position 3; + description + "One or more major alarms are active against the + resource."; + } + bit minor { + position 4; + description + "One or more minor alarms are active against the + resource."; + } + bit warning { + position 5; + description + "One or more warning alarms are active against the + resource."; + } + bit indeterminate { + position 6; + description + "One or more alarms of whose perceived severity cannot be + determined are active against this resource."; + } + } + description + "Represents the possible values of alarm states. An alarm is a + persistent indication of an error or warning condition. + When no bits of this attribute are set, then no active alarms + are known against this component and it is not under repair."; + reference + "RFC 4268: Entity State MIB - EntityAlarmStatus"; +} + +typedef standby-state { + type enumeration { + enum unknown { + value 1; + description + "The resource is unable to report standby state."; + } + enum hot-standby { + value 2; + description + "The resource is not providing service, but it will be + immediately able to take over the role of the resource to + be backed up, without the need for initialization + activity, and will contain the same information as the + resource to be backed up."; + } + enum cold-standby { + value 3; + description + "The resource is to back up another resource, but it will + not be immediately able to take over the role of a + resource to be backed up and will require some + initialization activity."; + } + enum providing-service { + value 4; + description + "The resource is providing service."; + } + } + description + "Represents the possible values of standby states."; + reference + "RFC 4268: Entity State MIB - EntityStandbyStatus"; +} + +typedef sensor-value-type { + type enumeration { + enum other { + value 1; + description + "A measure other than those listed below."; + } + enum unknown { + value 2; + description + "An unknown measurement or arbitrary, relative numbers"; + } + enum volts-AC { + value 3; + description + "A measure of electric potential (alternating current)."; + } + enum volts-DC { + value 4; + description + "A measure of electric potential (direct current)."; + } + enum amperes { + value 5; + description + "A measure of electric current."; + } + enum watts { + value 6; + description + "A measure of power."; + } + enum hertz { + value 7; + description + "A measure of frequency."; + } + enum celsius { + value 8; + description + "A measure of temperature."; + } + enum percent-RH { + value 9; + description + "A measure of percent relative humidity."; + } + enum rpm { + value 10; + description + "A measure of shaft revolutions per minute."; + } + enum cmm { + value 11; + description + "A measure of cubic meters per minute (airflow)."; + } + enum truth-value { + value 12; + description + "Value is one of 1 (true) or 2 (false)"; + } + } + description + "A node using this data type represents the sensor measurement + data type associated with a physical sensor value. The actual + data units are determined by examining a node of this type + together with the associated sensor-value-scale node. + A node of this type SHOULD be defined together with nodes of + type sensor-value-scale and type sensor-value-precision. + These three types are used to identify the semantics of a node + of type sensor-value."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorDataType"; +} + +typedef sensor-value-scale { + type enumeration { + enum yocto { + value 1; + description + "Data scaling factor of 10^-24."; + } + enum zepto { + value 2; + description + "Data scaling factor of 10^-21."; + } + enum atto { + value 3; + description + "Data scaling factor of 10^-18."; + } + enum femto { + value 4; + description + "Data scaling factor of 10^-15."; + } + enum pico { + value 5; + description + "Data scaling factor of 10^-12."; + } + enum nano { + value 6; + description + "Data scaling factor of 10^-9."; + } + enum micro { + value 7; + description + "Data scaling factor of 10^-6."; + } + enum milli { + value 8; + description + "Data scaling factor of 10^-3."; + } + enum units { + value 9; + description + "Data scaling factor of 10^0."; + } + enum kilo { + value 10; + description + "Data scaling factor of 10^3."; + } + enum mega { + value 11; + description + "Data scaling factor of 10^6."; + } + enum giga { + value 12; + description + "Data scaling factor of 10^9."; + } + enum tera { + value 13; + description + "Data scaling factor of 10^12."; + } + enum peta { + value 14; + description + "Data scaling factor of 10^15."; + } + enum exa { + value 15; + description + "Data scaling factor of 10^18."; + } + enum zetta { + value 16; + description + "Data scaling factor of 10^21."; + } + enum yotta { + value 17; + description + "Data scaling factor of 10^24."; + } + } + description + "A node using this data type represents a data scaling factor, + represented with an International System of Units (SI) prefix. + The actual data units are determined by examining a node of + this type together with the associated sensor-value-type. + A node of this type SHOULD be defined together with nodes of + type sensor-value-type and type sensor-value-precision. + Together, associated nodes of these three types are used to + identify the semantics of a node of type sensor-value."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorDataScale"; +} + +typedef sensor-value-precision { + type int8 { + range "-8 .. 9"; + } + description + "A node using this data type represents a sensor value + precision range. + A node of this type SHOULD be defined together with nodes of + type sensor-value-type and type sensor-value-scale. Together, + associated nodes of these three types are used to identify the + semantics of a node of type sensor-value. + If a node of this type contains a value in the range 1 to 9, + it represents the number of decimal places in the fractional + part of an associated sensor-value fixed-point number. + If a node of this type contains a value in the range -8 to -1, + it represents the number of accurate digits in the associated + sensor-value fixed-point number. + The value zero indicates the associated sensor-value node is + not a fixed-point number. + Server implementers must choose a value for the associated + sensor-value-precision node so that the precision and accuracy + of the associated sensor-value node is correctly indicated. + For example, a component representing a temperature sensor + that can measure 0 to 100 degrees C in 0.1 degree + increments, +/- 0.05 degrees, would have a + sensor-value-precision value of '1', a sensor-value-scale + value of 'units', and a sensor-value ranging from '0' to + '1000'. The sensor-value would be interpreted as + 'degrees C * 10'."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorPrecision"; +} + +typedef sensor-value { + type int32 { + range "-1000000000 .. 1000000000"; + } + description + "A node using this data type represents a sensor value. + A node of this type SHOULD be defined together with nodes of + type sensor-value-type, type sensor-value-scale, and + type sensor-value-precision. Together, associated nodes of + those three types are used to identify the semantics of a node + of this data type. + The semantics of a node using this data type are determined by + the value of the associated sensor-value-type node. + If the associated sensor-value-type node is equal to 'voltsAC', + 'voltsDC', 'amperes', 'watts', 'hertz', 'celsius', or 'cmm', + then a node of this type MUST contain a fixed-point number + ranging from -999,999,999 to +999,999,999. The value + -1000000000 indicates an underflow error. The value + +1000000000 indicates an overflow error. The + sensor-value-precision indicates how many fractional digits + are represented in the associated sensor-value node. + If the associated sensor-value-type node is equal to + 'percentRH', then a node of this type MUST contain a number + ranging from 0 to 100. + If the associated sensor-value-type node is equal to 'rpm', + then a node of this type MUST contain a number ranging from + -999,999,999 to +999,999,999. + If the associated sensor-value-type node is equal to + 'truth-value', then a node of this type MUST contain either the + value 1 (true) or the value 2 (false). + If the associated sensor-value-type node is equal to 'other' or + 'unknown', then a node of this type MUST contain a number + ranging from -1000000000 to 1000000000."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorValue"; +} + +typedef sensor-status { + type enumeration { + enum ok { + value 1; + description + "Indicates that the server can obtain the sensor value."; + } + enum unavailable { + value 2; + description + "Indicates that the server presently cannot obtain the + sensor value."; + } + enum nonoperational { + value 3; + description + "Indicates that the server believes the sensor is broken. + The sensor could have a hard failure (disconnected wire) + or a soft failure such as out-of-range, jittery, or wildly + fluctuating readings."; + } + } + description + "A node using this data type represents the operational status + of a physical sensor."; + reference + "RFC 3433: Entity Sensor Management Information Base - + EntitySensorStatus"; +} + +/* + * Data nodes + */ + +container hardware { + description + "Data nodes representing components. + If the server supports configuration of hardware components, + then this data model is instantiated in the configuration + datastores supported by the server. The leaf-list 'datastore' + for the module 'ietf-hardware' in the YANG library provides + this information."; + + leaf last-change { + type yang:date-and-time; + config false; + description + "The time the '/hardware/component' list changed in the + operational state."; + } + + list component { + key name; + description + "List of components. + When the server detects a new hardware component, it + initializes a list entry in the operational state. + If the server does not support configuration of hardware + components, list entries in the operational state are + initialized with values for all nodes as detected by the + implementation. + Otherwise, this procedure is followed: + 1. If there is an entry in the '/hardware/component' list + in the intended configuration with values for the nodes + 'class', 'parent', and 'parent-rel-pos' that are equal + to the detected values, then the list entry in the + operational state is initialized with the configured + values, including the 'name'. + 2. Otherwise (i.e., there is no matching configuration + entry), the list entry in the operational state is + initialized with values for all nodes as detected by + the implementation. + If the '/hardware/component' list in the intended + configuration is modified, then the system MUST behave as if + it re-initializes itself and follow the procedure in (1)."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalEntry"; + + leaf name { + type string; + description + "The name assigned to this component. + This name is not required to be the same as + entPhysicalName."; + } + + leaf class { + type identityref { + base ianahw:hardware-class; + } + mandatory true; + description + "An indication of the general hardware type of the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalClass"; + } + + leaf physical-index { + if-feature entity-mib; + type int32 { + range "1..2147483647"; + } + config false; + description + "The entPhysicalIndex for the entPhysicalEntry represented + by this list entry."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalIndex"; + } + + leaf description { + type string; + config false; + description + "A textual description of the component. This node should + contain a string that identifies the manufacturer's name + for the component and should be set to a distinct value + for each version or model of the component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalDescr"; + } + + leaf parent { + type leafref { + path "../../component/name"; + require-instance false; + } + description + "The name of the component that physically contains this + component. + If this leaf is not instantiated, it indicates that this + component is not contained in any other component. + In the event that a physical component is contained by + more than one physical component (e.g., double-wide + modules), this node contains the name of one of these + components. An implementation MUST use the same name + every time this node is instantiated."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalContainedIn"; + } + + leaf parent-rel-pos { + type int32 { + range "0 .. 2147483647"; + } + description + "An indication of the relative position of this child + component among all its sibling components. Sibling + components are defined as components that: + o share the same value of the 'parent' node and + o share a common base identity for the 'class' node. + Note that the last rule gives implementations flexibility + in how components are numbered. For example, some + implementations might have a single number series for all + components derived from 'ianahw:port', while some others + might have different number series for different + components with identities derived from 'ianahw:port' (for + example, one for registered jack 45 (RJ45) and one for + small form-factor pluggable (SFP))."; + + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalParentRelPos"; + } + + leaf-list contains-child { + type leafref { + path "../../component/name"; + } + config false; + description + "The name of the contained component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalChildIndex"; + } + + leaf hardware-rev { + type string; + config false; + description + "The vendor-specific hardware revision string for the + component. The preferred value is the hardware revision + identifier actually printed on the component itself (if + present)."; + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalHardwareRev"; + } + + leaf firmware-rev { + type string; + config false; + description + "The vendor-specific firmware revision string for the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalFirmwareRev"; + } + + leaf software-rev { + type string; + config false; + + description + "The vendor-specific software revision string for the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - + entPhysicalSoftwareRev"; + } + + leaf serial-num { + type string; + config false; + description + "The vendor-specific serial number string for the + component. The preferred value is the serial number + string actually printed on the component itself (if + present)."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalSerialNum"; + } + + leaf mfg-name { + type string; + config false; + description + "The name of the manufacturer of this physical component. + The preferred value is the manufacturer name string + actually printed on the component itself (if present). + Note that comparisons between instances of the + 'model-name', 'firmware-rev', 'software-rev', and + 'serial-num' nodes are only meaningful amongst components + with the same value of 'mfg-name'. + If the manufacturer name string associated with the + physical component is unknown to the server, then this + node is not instantiated."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalMfgName"; + } + + leaf model-name { + type string; + config false; + description + "The vendor-specific model name identifier string + associated with this physical component. The preferred + value is the customer-visible part number, which may be + printed on the component itself. + If the model name string associated with the physical + component is unknown to the server, then this node is not + instantiated."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalModelName"; + } + + leaf alias { + type string; + description + "An 'alias' name for the component, as specified by a + network manager, that provides a non-volatile 'handle' for + the component. + If no configured value exists, the server MAY set the + value of this node to a locally unique value in the + operational state. + A server implementation MAY map this leaf to the + entPhysicalAlias MIB object. Such an implementation needs + to use some mechanism to handle the differences in size + and characters allowed between this leaf and + entPhysicalAlias. The definition of such a mechanism is + outside the scope of this document."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalAlias"; + } + + leaf asset-id { + type string; + description + "This node is a user-assigned asset tracking identifier for + the component. + A server implementation MAY map this leaf to the + entPhysicalAssetID MIB object. Such an implementation + needs to use some mechanism to handle the differences in + size and characters allowed between this leaf and + entPhysicalAssetID. The definition of such a mechanism is + outside the scope of this document."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalAssetID"; + } + + leaf is-fru { + type boolean; + config false; + + description + "This node indicates whether or not this component is + considered a 'field-replaceable unit' by the vendor. If + this node contains the value 'true', then this component + identifies a field-replaceable unit. For all components + that are permanently contained within a field-replaceable + unit, the value 'false' should be returned for this + node."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalIsFRU"; + } + + leaf mfg-date { + type yang:date-and-time; + config false; + description + "The date of manufacturing of the managed component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalMfgDate"; + } + + leaf-list uri { + type inet:uri; + description + "This node contains identification information about the + component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalUris"; + } + + leaf uuid { + type yang:uuid; + config false; + description + "A Universally Unique Identifier of the component."; + reference + "RFC 6933: Entity MIB (Version 4) - entPhysicalUUID"; + } + + container state { + if-feature hardware-state; + description + "State-related nodes"; + reference + "RFC 4268: Entity State MIB"; + + leaf state-last-changed { + type yang:date-and-time; + config false; + description + "The date and time when the value of any of the + admin-state, oper-state, usage-state, alarm-state, or + standby-state changed for this component. + If there has been no change since the last + re-initialization of the local system, this node + contains the date and time of local system + initialization. If there has been no change since the + component was added to the local system, this node + contains the date and time of the insertion."; + reference + "RFC 4268: Entity State MIB - entStateLastChanged"; + } + + leaf admin-state { + type admin-state; + description + "The administrative state for this component. + This node refers to a component's administrative + permission to service both other components within its + containment hierarchy as well other users of its + services defined by means outside the scope of this + module. + Some components exhibit only a subset of the remaining + administrative state values. Some components cannot be + locked; hence, this node exhibits only the 'unlocked' + state. Other components cannot be shut down gracefully; + hence, this node does not exhibit the 'shutting-down' + state."; + reference + "RFC 4268: Entity State MIB - entStateAdmin"; + } + + leaf oper-state { + type oper-state; + config false; + description + "The operational state for this component. + Note that this node does not follow the administrative + state. An administrative state of 'down' does not + predict an operational state of 'disabled'. + Note that some implementations may not be able to + accurately report oper-state while the admin-state node + has a value other than 'unlocked'. In these cases, this + node MUST have a value of 'unknown'."; + reference + "RFC 4268: Entity State MIB - entStateOper"; + } + + leaf usage-state { + type usage-state; + config false; + description + "The usage state for this component. + This node refers to a component's ability to service + more components in a containment hierarchy. + Some components will exhibit only a subset of the usage + state values. Components that are unable to ever + service any components within a containment hierarchy + will always have a usage state of 'busy'. In some + cases, a component will be able to support only one + other component within its containment hierarchy and + will therefore only exhibit values of 'idle' and + 'busy'."; + reference + "RFC 4268: Entity State MIB - entStateUsage"; + } + + leaf alarm-state { + type alarm-state; + config false; + description + "The alarm state for this component. It does not + include the alarms raised on child components within its + containment hierarchy."; + reference + "RFC 4268: Entity State MIB - entStateAlarm"; + } + + leaf standby-state { + type standby-state; + config false; + description + "The standby state for this component. + Some components will exhibit only a subset of the + remaining standby state values. If this component + cannot operate in a standby role, the value of this node + will always be 'providing-service'."; + reference + "RFC 4268: Entity State MIB - entStateStandby"; + } + } + + container sensor-data { + when 'derived-from-or-self(../class, + "ianahw:sensor")' { + description + "Sensor data nodes present for any component of type + 'sensor'"; + } + if-feature hardware-sensor; + config false; + + description + "Sensor-related nodes."; + reference + "RFC 3433: Entity Sensor Management Information Base"; + + leaf value { + type sensor-value; + description + "The most recent measurement obtained by the server + for this sensor. + A client that periodically fetches this node should also + fetch the nodes 'value-type', 'value-scale', and + 'value-precision', since they may change when the value + is changed."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorValue"; + } + + leaf value-type { + type sensor-value-type; + description + "The type of data units associated with the + sensor value"; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorType"; + } + leaf value-scale { + type sensor-value-scale; + description + "The (power of 10) scaling factor associated + with the sensor value"; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorScale"; + } + + leaf value-precision { + type sensor-value-precision; + description + "The number of decimal places of precision + associated with the sensor value"; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorPrecision"; + } + + leaf oper-status { + type sensor-status; + description + "The operational status of the sensor."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorOperStatus"; + } + + leaf units-display { + type string; + description + "A textual description of the data units that should be + used in the display of the sensor value."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorUnitsDisplay"; + } + + leaf value-timestamp { + type yang:date-and-time; + description + "The time the status and/or value of this sensor was last + obtained by the server."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorValueTimeStamp"; + } + leaf value-update-rate { + type uint32; + units "milliseconds"; + description + "An indication of the frequency that the server updates + the associated 'value' node, represented in + milliseconds. The value zero indicates: + - the sensor value is updated on demand (e.g., + when polled by the server for a get-request), + - the sensor value is updated when the sensor + value changes (event-driven), or + - the server does not know the update rate."; + reference + "RFC 3433: Entity Sensor Management Information Base - + entPhySensorValueUpdateRate"; + } + } + } +} + +/* + * Notifications + */ + +notification hardware-state-change { + description + "A hardware-state-change notification is generated when the + value of /hardware/last-change changes in the operational + state."; + reference + "RFC 6933: Entity MIB (Version 4) - entConfigChange"; +} + +notification hardware-state-oper-enabled { + if-feature hardware-state; + description + "A hardware-state-oper-enabled notification signifies that a + component has transitioned into the 'enabled' state."; + + leaf name { + type leafref { + path "/hardware/component/name"; + } + + description + "The name of the component that has transitioned into the + 'enabled' state."; + } + leaf admin-state { + type leafref { + path "/hardware/component/state/admin-state"; + } + description + "The administrative state for the component."; + } + leaf alarm-state { + type leafref { + path "/hardware/component/state/alarm-state"; + } + description + "The alarm state for the component."; + } + reference + "RFC 4268: Entity State MIB - entStateOperEnabled"; +} + +notification hardware-state-oper-disabled { + if-feature hardware-state; + description + "A hardware-state-oper-disabled notification signifies that a + component has transitioned into the 'disabled' state."; + + leaf name { + type leafref { + path "/hardware/component/name"; + } + description + "The name of the component that has transitioned into the + 'disabled' state."; + } + leaf admin-state { + type leafref { + path "/hardware/component/state/admin-state"; + } + description + "The administrative state for the component."; + } + leaf alarm-state { + type leafref { + path "/hardware/component/state/alarm-state"; + } + + description + "The alarm state for the component."; + } + reference + "RFC 4268: Entity State MIB - entStateOperDisabled"; +} + +} diff --git a/radio/fhi_72/mplane/yang/models/ietf-interfaces.yang b/radio/fhi_72/mplane/yang/models/ietf-interfaces.yang new file mode 100644 index 0000000000..8dae9d3e21 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/ietf-interfaces.yang @@ -0,0 +1,1073 @@ +module ietf-interfaces { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces"; + prefix if; + + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETMOD (Network Modeling) Working Group"; + + contact + "WG Web: + WG List: + Editor: Martin Bjorklund + "; + + description + "This module contains a collection of YANG definitions for + managing network interfaces. + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 8343; see + the RFC itself for full legal notices."; + + revision 2018-02-20 { + description + "Updated to support NMDA."; + reference + "RFC 8343: A YANG Data Model for Interface Management"; + } + + revision 2014-05-08 { + description + "Initial revision."; + reference + "RFC 7223: A YANG Data Model for Interface Management"; + } + + /* + * Typedefs + */ + + typedef interface-ref { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + description + "This type is used by data models that need to reference + interfaces."; + } + + /* + * Identities + */ + + identity interface-type { + description + "Base identity from which specific interface types are + derived."; + } + + /* + * Features + */ + + feature arbitrary-names { + description + "This feature indicates that the device allows user-controlled + interfaces to be named arbitrarily."; + } + feature pre-provisioning { + description + "This feature indicates that the device supports + pre-provisioning of interface configuration, i.e., it is + possible to configure an interface whose physical interface + hardware is not present on the device."; + } + feature if-mib { + description + "This feature indicates that the device implements + the IF-MIB."; + reference + "RFC 2863: The Interfaces Group MIB"; + } + + /* + * Data nodes + */ + + container interfaces { + description + "Interface parameters."; + + list interface { + key "name"; + + description + "The list of interfaces on the device. + The status of an interface is available in this list in the + operational state. If the configuration of a + system-controlled interface cannot be used by the system + (e.g., the interface hardware present does not match the + interface type), then the configuration is not applied to + the system-controlled interface shown in the operational + state. If the configuration of a user-controlled interface + cannot be used by the system, the configured interface is + not instantiated in the operational state. + System-controlled interfaces created by the system are + always present in this list in the operational state, + whether or not they are configured."; + + leaf name { + type string; + description + "The name of the interface. + A device MAY restrict the allowed values for this leaf, + possibly depending on the type of the interface. + For system-controlled interfaces, this leaf is the + device-specific name of the interface. + If a client tries to create configuration for a + system-controlled interface that is not present in the + operational state, the server MAY reject the request if + the implementation does not support pre-provisioning of + interfaces or if the name refers to an interface that can + never exist in the system. A Network Configuration + Protocol (NETCONF) server MUST reply with an rpc-error + with the error-tag 'invalid-value' in this case. + If the device supports pre-provisioning of interface + configuration, the 'pre-provisioning' feature is + advertised. + If the device allows arbitrarily named user-controlled + interfaces, the 'arbitrary-names' feature is advertised. + When a configured user-controlled interface is created by + the system, it is instantiated with the same name in the + operational state. + A server implementation MAY map this leaf to the ifName + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifName. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 2863: The Interfaces Group MIB - ifName"; + } + + leaf description { + type string; + description + "A textual description of the interface. + A server implementation MAY map this leaf to the ifAlias + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifAlias. The definition of + such a mechanism is outside the scope of this document. + Since ifAlias is defined to be stored in non-volatile + storage, the MIB implementation MUST map ifAlias to the + value of 'description' in the persistently stored + configuration."; + reference + "RFC 2863: The Interfaces Group MIB - ifAlias"; + } + + leaf type { + type identityref { + base interface-type; + } + mandatory true; + description + "The type of the interface. + When an interface entry is created, a server MAY + initialize the type leaf with a valid value, e.g., if it + is possible to derive the type from the name of the + interface. + If a client tries to set the type of an interface to a + value that can never be used by the system, e.g., if the + type is not supported or if the type does not match the + name of the interface, the server MUST reject the request. + A NETCONF server MUST reply with an rpc-error with the + error-tag 'invalid-value' in this case."; + reference + "RFC 2863: The Interfaces Group MIB - ifType"; + } + + leaf enabled { + type boolean; + default "true"; + description + "This leaf contains the configured, desired state of the + interface. + Systems that implement the IF-MIB use the value of this + leaf in the intended configuration to set + IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry + has been initialized, as described in RFC 2863. + Changes in this leaf in the intended configuration are + reflected in ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf link-up-down-trap-enable { + if-feature if-mib; + type enumeration { + enum enabled { + value 1; + description + "The device will generate linkUp/linkDown SNMP + notifications for this interface."; + } + enum disabled { + value 2; + description + "The device will not generate linkUp/linkDown SNMP + notifications for this interface."; + } + } + description + "Controls whether linkUp/linkDown SNMP notifications + should be generated for this interface. + If this node is not configured, the value 'enabled' is + operationally used by the server for interfaces that do + not operate on top of any other interface (i.e., there are + no 'lower-layer-if' entries), and 'disabled' otherwise."; + reference + "RFC 2863: The Interfaces Group MIB - + ifLinkUpDownTrapEnable"; + } + + leaf admin-status { + if-feature if-mib; + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "Not ready to pass packets and not in some test mode."; + } + enum testing { + value 3; + description + "In some test mode."; + } + } + config false; + mandatory true; + description + "The desired state of the interface. + This leaf has the same read semantics as ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf oper-status { + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + + description + "The interface does not pass any packets."; + } + enum testing { + value 3; + description + "In some test mode. No operational packets can + be passed."; + } + enum unknown { + value 4; + description + "Status cannot be determined for some reason."; + } + enum dormant { + value 5; + description + "Waiting for some external event."; + } + enum not-present { + value 6; + description + "Some component (typically hardware) is missing."; + } + enum lower-layer-down { + value 7; + description + "Down due to state of lower-layer interface(s)."; + } + } + config false; + mandatory true; + description + "The current operational state of the interface. + This leaf has the same semantics as ifOperStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifOperStatus"; + } + + leaf last-change { + type yang:date-and-time; + config false; + description + "The time the interface entered its current operational + state. If the current state was entered prior to the + last re-initialization of the local network management + subsystem, then this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifLastChange"; + } + + leaf if-index { + if-feature if-mib; + type int32 { + range "1..2147483647"; + } + config false; + mandatory true; + description + "The ifIndex value for the ifEntry represented by this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifIndex"; + } + + leaf phys-address { + type yang:phys-address; + config false; + description + "The interface's address at its protocol sub-layer. For + example, for an 802.x interface, this object normally + contains a Media Access Control (MAC) address. The + interface's media-specific modules must define the bit + and byte ordering and the format of the value of this + object. For interfaces that do not have such an address + (e.g., a serial line), this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifPhysAddress"; + } + + leaf-list higher-layer-if { + type interface-ref; + config false; + description + "A list of references to interfaces layered on top of this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf-list lower-layer-if { + type interface-ref; + config false; + + description + "A list of references to interfaces layered underneath this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf speed { + type yang:gauge64; + units "bits/second"; + config false; + description + "An estimate of the interface's current bandwidth in bits + per second. For interfaces that do not vary in + bandwidth or for those where no accurate estimation can + be made, this node should contain the nominal bandwidth. + For interfaces that have no concept of bandwidth, this + node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - + ifSpeed, ifHighSpeed"; + } + + container statistics { + config false; + description + "A collection of interface-related statistics objects."; + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + description + "The time on the most recent occasion at which any one or + more of this interface's counters suffered a + discontinuity. If no such discontinuities have occurred + since the last re-initialization of the local management + subsystem, then this node contains the time the local + management subsystem re-initialized itself."; + } + + leaf in-octets { + type yang:counter64; + description + "The total number of octets received on the interface, + including framing characters. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInOctets"; + } + + leaf in-unicast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were not addressed to a + multicast or broadcast address at this sub-layer. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts"; + } + + leaf in-broadcast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a broadcast + address at this sub-layer. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInBroadcastPkts"; + } + + leaf in-multicast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a multicast + address at this sub-layer. For a MAC-layer protocol, + this includes both Group and Functional addresses. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInMulticastPkts"; + } + + leaf in-discards { + type yang:counter32; + description + "The number of inbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being deliverable to a higher-layer + protocol. One possible reason for discarding such a + packet could be to free up buffer space. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInDiscards"; + } + + leaf in-errors { + type yang:counter32; + description + "For packet-oriented interfaces, the number of inbound + packets that contained errors preventing them from being + deliverable to a higher-layer protocol. For character- + oriented or fixed-length interfaces, the number of + inbound transmission units that contained errors + preventing them from being deliverable to a higher-layer + protocol. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInErrors"; + } + + leaf in-unknown-protos { + type yang:counter32; + + description + "For packet-oriented interfaces, the number of packets + received via the interface that were discarded because + of an unknown or unsupported protocol. For + character-oriented or fixed-length interfaces that + support protocol multiplexing, the number of + transmission units received via the interface that were + discarded because of an unknown or unsupported protocol. + For any interface that does not support protocol + multiplexing, this counter is not present. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos"; + } + + leaf out-octets { + type yang:counter64; + description + "The total number of octets transmitted out of the + interface, including framing characters. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutOctets"; + } + + leaf out-unicast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were not addressed + to a multicast or broadcast address at this sub-layer, + including those that were discarded or not sent. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts"; + } + + leaf out-broadcast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + broadcast address at this sub-layer, including those + that were discarded or not sent. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutBroadcastPkts"; + } + + leaf out-multicast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + multicast address at this sub-layer, including those + that were discarded or not sent. For a MAC-layer + protocol, this includes both Group and Functional + addresses. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutMulticastPkts"; + } + + leaf out-discards { + type yang:counter32; + description + "The number of outbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being transmitted. One possible reason + for discarding such a packet could be to free up buffer + space. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutDiscards"; + } + + leaf out-errors { + type yang:counter32; + description + "For packet-oriented interfaces, the number of outbound + packets that could not be transmitted because of errors. + For character-oriented or fixed-length interfaces, the + number of outbound transmission units that could not be + transmitted because of errors. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutErrors"; + } + } + + } + } + + /* + * Legacy typedefs + */ + + typedef interface-state-ref { + type leafref { + path "/if:interfaces-state/if:interface/if:name"; + } + status deprecated; + description + "This type is used by data models that need to reference + the operationally present interfaces."; + } + + /* + * Legacy operational state data nodes + */ + + container interfaces-state { + config false; + status deprecated; + description + "Data nodes for the operational state of interfaces."; + + list interface { + key "name"; + status deprecated; + + description + "The list of interfaces on the device. + System-controlled interfaces created by the system are + always present in this list, whether or not they are + configured."; + + leaf name { + type string; + status deprecated; + description + "The name of the interface. + A server implementation MAY map this leaf to the ifName + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifName. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 2863: The Interfaces Group MIB - ifName"; + } + + leaf type { + type identityref { + base interface-type; + } + mandatory true; + status deprecated; + description + "The type of the interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifType"; + } + + leaf admin-status { + if-feature if-mib; + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "Not ready to pass packets and not in some test mode."; + } + enum testing { + value 3; + description + "In some test mode."; + } + } + mandatory true; + status deprecated; + description + "The desired state of the interface. + This leaf has the same read semantics as ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf oper-status { + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "The interface does not pass any packets."; + } + enum testing { + value 3; + description + "In some test mode. No operational packets can + be passed."; + } + enum unknown { + value 4; + description + "Status cannot be determined for some reason."; + } + enum dormant { + value 5; + description + "Waiting for some external event."; + } + enum not-present { + value 6; + description + "Some component (typically hardware) is missing."; + } + enum lower-layer-down { + value 7; + description + "Down due to state of lower-layer interface(s)."; + } + } + mandatory true; + status deprecated; + description + "The current operational state of the interface. + This leaf has the same semantics as ifOperStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifOperStatus"; + } + + leaf last-change { + type yang:date-and-time; + status deprecated; + description + "The time the interface entered its current operational + state. If the current state was entered prior to the + last re-initialization of the local network management + subsystem, then this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifLastChange"; + } + + leaf if-index { + if-feature if-mib; + type int32 { + range "1..2147483647"; + } + mandatory true; + status deprecated; + description + "The ifIndex value for the ifEntry represented by this + interface."; + + reference + "RFC 2863: The Interfaces Group MIB - ifIndex"; + } + + leaf phys-address { + type yang:phys-address; + status deprecated; + description + "The interface's address at its protocol sub-layer. For + example, for an 802.x interface, this object normally + contains a Media Access Control (MAC) address. The + interface's media-specific modules must define the bit + and byte ordering and the format of the value of this + object. For interfaces that do not have such an address + (e.g., a serial line), this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifPhysAddress"; + } + + leaf-list higher-layer-if { + type interface-state-ref; + status deprecated; + description + "A list of references to interfaces layered on top of this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf-list lower-layer-if { + type interface-state-ref; + status deprecated; + description + "A list of references to interfaces layered underneath this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf speed { + type yang:gauge64; + units "bits/second"; + status deprecated; + description + "An estimate of the interface's current bandwidth in bits + per second. For interfaces that do not vary in + bandwidth or for those where no accurate estimation can + be made, this node should contain the nominal bandwidth. + For interfaces that have no concept of bandwidth, this + node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - + ifSpeed, ifHighSpeed"; + } + + container statistics { + status deprecated; + description + "A collection of interface-related statistics objects."; + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + status deprecated; + description + "The time on the most recent occasion at which any one or + more of this interface's counters suffered a + discontinuity. If no such discontinuities have occurred + since the last re-initialization of the local management + subsystem, then this node contains the time the local + management subsystem re-initialized itself."; + } + + leaf in-octets { + type yang:counter64; + status deprecated; + description + "The total number of octets received on the interface, + including framing characters. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInOctets"; + } + + leaf in-unicast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were not addressed to a + multicast or broadcast address at this sub-layer. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts"; + } + + leaf in-broadcast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a broadcast + address at this sub-layer. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInBroadcastPkts"; + } + + leaf in-multicast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a multicast + address at this sub-layer. For a MAC-layer protocol, + this includes both Group and Functional addresses. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInMulticastPkts"; + } + + leaf in-discards { + type yang:counter32; + status deprecated; + + description + "The number of inbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being deliverable to a higher-layer + protocol. One possible reason for discarding such a + packet could be to free up buffer space. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInDiscards"; + } + + leaf in-errors { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of inbound + packets that contained errors preventing them from being + deliverable to a higher-layer protocol. For character- + oriented or fixed-length interfaces, the number of + inbound transmission units that contained errors + preventing them from being deliverable to a higher-layer + protocol. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInErrors"; + } + + leaf in-unknown-protos { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of packets + received via the interface that were discarded because + of an unknown or unsupported protocol. For + character-oriented or fixed-length interfaces that + support protocol multiplexing, the number of + transmission units received via the interface that were + discarded because of an unknown or unsupported protocol. + For any interface that does not support protocol + multiplexing, this counter is not present. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos"; + } + + leaf out-octets { + type yang:counter64; + status deprecated; + description + "The total number of octets transmitted out of the + interface, including framing characters. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutOctets"; + } + + leaf out-unicast-pkts { + type yang:counter64; + status deprecated; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were not addressed + to a multicast or broadcast address at this sub-layer, + including those that were discarded or not sent. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts"; + } + + leaf out-broadcast-pkts { + type yang:counter64; + status deprecated; + + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + broadcast address at this sub-layer, including those + that were discarded or not sent. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutBroadcastPkts"; + } + + leaf out-multicast-pkts { + type yang:counter64; + status deprecated; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + multicast address at this sub-layer, including those + that were discarded or not sent. For a MAC-layer + protocol, this includes both Group and Functional + addresses. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutMulticastPkts"; + } + + leaf out-discards { + type yang:counter32; + status deprecated; + description + "The number of outbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being transmitted. One possible reason + for discarding such a packet could be to free up buffer + space. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutDiscards"; + } + + leaf out-errors { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of outbound + packets that could not be transmitted because of errors. + For character-oriented or fixed-length interfaces, the + number of outbound transmission units that could not be + transmitted because of errors. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutErrors"; + } + } + } + } +} diff --git a/radio/fhi_72/mplane/yang/models/ietf-ip.yang b/radio/fhi_72/mplane/yang/models/ietf-ip.yang new file mode 100644 index 0000000000..449081b5c9 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/ietf-ip.yang @@ -0,0 +1,860 @@ +module ietf-ip { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-ip"; + prefix ip; + + import ietf-interfaces { + prefix if; + } + import ietf-inet-types { + prefix inet; + } + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETMOD (Network Modeling) Working Group"; + + contact + "WG Web: + WG List: + Editor: Martin Bjorklund + "; + description + "This module contains a collection of YANG definitions for + managing IP implementations. + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 8344; see + the RFC itself for full legal notices."; + + revision 2018-02-22 { + description + "Updated to support NMDA."; + reference + "RFC 8344: A YANG Data Model for IP Management"; + } + + revision 2014-06-16 { + description + "Initial revision."; + reference + "RFC 7277: A YANG Data Model for IP Management"; + } + + /* + * Features + */ + + feature ipv4-non-contiguous-netmasks { + description + "Indicates support for configuring non-contiguous + subnet masks."; + } + + feature ipv6-privacy-autoconf { + description + "Indicates support for privacy extensions for stateless address + autoconfiguration in IPv6."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6"; + } + + /* + * Typedefs + */ + + typedef ip-address-origin { + type enumeration { + enum other { + description + "None of the following."; + } + + enum static { + description + "Indicates that the address has been statically + configured -- for example, using the Network Configuration + Protocol (NETCONF) or a command line interface."; + } + enum dhcp { + description + "Indicates an address that has been assigned to this + system by a DHCP server."; + } + enum link-layer { + description + "Indicates an address created by IPv6 stateless + autoconfiguration that embeds a link-layer address in its + interface identifier."; + } + enum random { + description + "Indicates an address chosen by the system at + random, e.g., an IPv4 address within 169.254/16, a + temporary address as described in RFC 4941, or a + semantically opaque address as described in RFC 7217."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6 + RFC 7217: A Method for Generating Semantically Opaque + Interface Identifiers with IPv6 Stateless + Address Autoconfiguration (SLAAC)"; + } + } + description + "The origin of an address."; + } + + typedef neighbor-origin { + type enumeration { + enum other { + description + "None of the following."; + } + enum static { + description + "Indicates that the mapping has been statically + configured -- for example, using NETCONF or a command line + interface."; + } + + enum dynamic { + description + "Indicates that the mapping has been dynamically resolved + using, for example, IPv4 ARP or the IPv6 Neighbor + Discovery protocol."; + } + } + description + "The origin of a neighbor entry."; + } + + /* + * Data nodes + */ + + augment "/if:interfaces/if:interface" { + description + "IP parameters on interfaces. + If an interface is not capable of running IP, the server + must not allow the client to configure these parameters."; + + container ipv4 { + presence + "Enables IPv4 unless the 'enabled' leaf + (which defaults to 'true') is set to 'false'"; + description + "Parameters for the IPv4 address family."; + + leaf enabled { + type boolean; + default true; + description + "Controls whether IPv4 is enabled or disabled on this + interface. When IPv4 is enabled, this interface is + connected to an IPv4 stack, and the interface can send + and receive IPv4 packets."; + } + leaf forwarding { + type boolean; + default false; + description + "Controls IPv4 packet forwarding of datagrams received by, + but not addressed to, this interface. IPv4 routers + forward datagrams. IPv4 hosts do not (except those + source-routed via the host)."; + } + + leaf mtu { + type uint16 { + range "68..max"; + } + units "octets"; + description + "The size, in octets, of the largest IPv4 packet that the + interface will send and receive. + The server may restrict the allowed values for this leaf, + depending on the interface's type. + If this leaf is not configured, the operationally used MTU + depends on the interface's type."; + reference + "RFC 791: Internet Protocol"; + } + list address { + key "ip"; + description + "The list of IPv4 addresses on the interface."; + + leaf ip { + type inet:ipv4-address-no-zone; + description + "The IPv4 address on the interface."; + } + choice subnet { + mandatory true; + description + "The subnet can be specified as a prefix length or, + if the server supports non-contiguous netmasks, as + a netmask."; + leaf prefix-length { + type uint8 { + range "0..32"; + } + description + "The length of the subnet prefix."; + } + leaf netmask { + if-feature ipv4-non-contiguous-netmasks; + type yang:dotted-quad; + description + "The subnet specified as a netmask."; + } + } + + leaf origin { + type ip-address-origin; + config false; + description + "The origin of this address."; + } + } + list neighbor { + key "ip"; + description + "A list of mappings from IPv4 addresses to + link-layer addresses. + Entries in this list in the intended configuration are + used as static entries in the ARP Cache. + In the operational state, this list represents the ARP + Cache."; + reference + "RFC 826: An Ethernet Address Resolution Protocol"; + + leaf ip { + type inet:ipv4-address-no-zone; + description + "The IPv4 address of the neighbor node."; + } + leaf link-layer-address { + type yang:phys-address; + mandatory true; + description + "The link-layer address of the neighbor node."; + } + leaf origin { + type neighbor-origin; + config false; + description + "The origin of this neighbor entry."; + } + } + } + + container ipv6 { + presence + "Enables IPv6 unless the 'enabled' leaf + (which defaults to 'true') is set to 'false'"; + description + "Parameters for the IPv6 address family."; + + leaf enabled { + type boolean; + default true; + description + "Controls whether IPv6 is enabled or disabled on this + interface. When IPv6 is enabled, this interface is + connected to an IPv6 stack, and the interface can send + and receive IPv6 packets."; + } + leaf forwarding { + type boolean; + default false; + description + "Controls IPv6 packet forwarding of datagrams received by, + but not addressed to, this interface. IPv6 routers + forward datagrams. IPv6 hosts do not (except those + source-routed via the host)."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 6.2.1, IsRouter"; + } + leaf mtu { + type uint32 { + range "1280..max"; + } + units "octets"; + description + "The size, in octets, of the largest IPv6 packet that the + interface will send and receive. + The server may restrict the allowed values for this leaf, + depending on the interface's type. + If this leaf is not configured, the operationally used MTU + depends on the interface's type."; + reference + "RFC 8200: Internet Protocol, Version 6 (IPv6) + Specification + Section 5"; + } + + list address { + key "ip"; + description + "The list of IPv6 addresses on the interface."; + + leaf ip { + type inet:ipv6-address-no-zone; + description + "The IPv6 address on the interface."; + } + leaf prefix-length { + type uint8 { + range "0..128"; + } + mandatory true; + description + "The length of the subnet prefix."; + } + leaf origin { + type ip-address-origin; + config false; + description + "The origin of this address."; + } + leaf status { + type enumeration { + enum preferred { + description + "This is a valid address that can appear as the + destination or source address of a packet."; + } + enum deprecated { + description + "This is a valid but deprecated address that should + no longer be used as a source address in new + communications, but packets addressed to such an + address are processed as expected."; + } + enum invalid { + description + "This isn't a valid address, and it shouldn't appear + as the destination or source address of a packet."; + } + + enum inaccessible { + description + "The address is not accessible because the interface + to which this address is assigned is not + operational."; + } + enum unknown { + description + "The status cannot be determined for some reason."; + } + enum tentative { + description + "The uniqueness of the address on the link is being + verified. Addresses in this state should not be + used for general communication and should only be + used to determine the uniqueness of the address."; + } + enum duplicate { + description + "The address has been determined to be non-unique on + the link and so must not be used."; + } + enum optimistic { + description + "The address is available for use, subject to + restrictions, while its uniqueness on a link is + being verified."; + } + } + config false; + description + "The status of an address. Most of the states correspond + to states from the IPv6 Stateless Address + Autoconfiguration protocol."; + reference + "RFC 4293: Management Information Base for the + Internet Protocol (IP) + - IpAddressStatusTC + RFC 4862: IPv6 Stateless Address Autoconfiguration"; + } + } + + list neighbor { + key "ip"; + description + "A list of mappings from IPv6 addresses to + link-layer addresses. + Entries in this list in the intended configuration are + used as static entries in the Neighbor Cache. + In the operational state, this list represents the + Neighbor Cache."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)"; + + leaf ip { + type inet:ipv6-address-no-zone; + description + "The IPv6 address of the neighbor node."; + } + leaf link-layer-address { + type yang:phys-address; + mandatory true; + description + "The link-layer address of the neighbor node. + In the operational state, if the neighbor's 'state' leaf + is 'incomplete', this leaf is not instantiated."; + } + leaf origin { + type neighbor-origin; + config false; + description + "The origin of this neighbor entry."; + } + leaf is-router { + type empty; + config false; + description + "Indicates that the neighbor node acts as a router."; + } + + leaf state { + type enumeration { + enum incomplete { + description + "Address resolution is in progress, and the + link-layer address of the neighbor has not yet been + determined."; + } + enum reachable { + description + "Roughly speaking, the neighbor is known to have been + reachable recently (within tens of seconds ago)."; + } + enum stale { + description + "The neighbor is no longer known to be reachable, but + until traffic is sent to the neighbor no attempt + should be made to verify its reachability."; + } + enum delay { + description + "The neighbor is no longer known to be reachable, and + traffic has recently been sent to the neighbor. + Rather than probe the neighbor immediately, however, + delay sending probes for a short while in order to + give upper-layer protocols a chance to provide + reachability confirmation."; + } + enum probe { + description + "The neighbor is no longer known to be reachable, and + unicast Neighbor Solicitation probes are being sent + to verify reachability."; + } + } + config false; + description + "The Neighbor Unreachability Detection state of this + entry."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 7.3.2"; + } + } + + leaf dup-addr-detect-transmits { + type uint32; + default 1; + description + "The number of consecutive Neighbor Solicitation messages + sent while performing Duplicate Address Detection on a + tentative address. A value of zero indicates that + Duplicate Address Detection is not performed on + tentative addresses. A value of one indicates a single + transmission with no follow-up retransmissions."; + reference + "RFC 4862: IPv6 Stateless Address Autoconfiguration"; + } + container autoconf { + description + "Parameters to control the autoconfiguration of IPv6 + addresses, as described in RFC 4862."; + reference + "RFC 4862: IPv6 Stateless Address Autoconfiguration"; + + leaf create-global-addresses { + type boolean; + default true; + description + "If enabled, the host creates global addresses as + described in RFC 4862."; + reference + "RFC 4862: IPv6 Stateless Address Autoconfiguration + Section 5.5"; + } + leaf create-temporary-addresses { + if-feature ipv6-privacy-autoconf; + type boolean; + default false; + description + "If enabled, the host creates temporary addresses as + described in RFC 4941."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6"; + } + + leaf temporary-valid-lifetime { + if-feature ipv6-privacy-autoconf; + type uint32; + units "seconds"; + default 604800; + description + "The time period during which the temporary address + is valid."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6 + - TEMP_VALID_LIFETIME"; + } + leaf temporary-preferred-lifetime { + if-feature ipv6-privacy-autoconf; + type uint32; + units "seconds"; + default 86400; + description + "The time period during which the temporary address is + preferred."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6 + - TEMP_PREFERRED_LIFETIME"; + } + } + } + } + + /* + * Legacy operational state data nodes + */ + + augment "/if:interfaces-state/if:interface" { + status deprecated; + description + "Data nodes for the operational state of IP on interfaces."; + + container ipv4 { + presence + "Present if IPv4 is enabled on this interface"; + config false; + status deprecated; + description + "Interface-specific parameters for the IPv4 address family."; + + leaf forwarding { + type boolean; + status deprecated; + description + "Indicates whether IPv4 packet forwarding is enabled or + disabled on this interface."; + } + leaf mtu { + type uint16 { + range "68..max"; + } + units "octets"; + status deprecated; + description + "The size, in octets, of the largest IPv4 packet that the + interface will send and receive."; + reference + "RFC 791: Internet Protocol"; + } + list address { + key "ip"; + status deprecated; + description + "The list of IPv4 addresses on the interface."; + + leaf ip { + type inet:ipv4-address-no-zone; + status deprecated; + description + "The IPv4 address on the interface."; + } + choice subnet { + status deprecated; + description + "The subnet can be specified as a prefix length or, + if the server supports non-contiguous netmasks, as + a netmask."; + leaf prefix-length { + type uint8 { + range "0..32"; + } + status deprecated; + description + "The length of the subnet prefix."; + } + leaf netmask { + if-feature ipv4-non-contiguous-netmasks; + type yang:dotted-quad; + status deprecated; + description + "The subnet specified as a netmask."; + } + } + leaf origin { + type ip-address-origin; + status deprecated; + description + "The origin of this address."; + } + } + list neighbor { + key "ip"; + status deprecated; + description + "A list of mappings from IPv4 addresses to + link-layer addresses. + This list represents the ARP Cache."; + reference + "RFC 826: An Ethernet Address Resolution Protocol"; + + leaf ip { + type inet:ipv4-address-no-zone; + status deprecated; + description + "The IPv4 address of the neighbor node."; + } + + leaf link-layer-address { + type yang:phys-address; + status deprecated; + description + "The link-layer address of the neighbor node."; + } + leaf origin { + type neighbor-origin; + status deprecated; + description + "The origin of this neighbor entry."; + } + } + } + + container ipv6 { + presence + "Present if IPv6 is enabled on this interface"; + config false; + status deprecated; + description + "Parameters for the IPv6 address family."; + + leaf forwarding { + type boolean; + default false; + status deprecated; + description + "Indicates whether IPv6 packet forwarding is enabled or + disabled on this interface."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 6.2.1, IsRouter"; + } + leaf mtu { + type uint32 { + range "1280..max"; + } + units "octets"; + status deprecated; + description + "The size, in octets, of the largest IPv6 packet that the + interface will send and receive."; + reference + "RFC 8200: Internet Protocol, Version 6 (IPv6) + Specification + Section 5"; + } + list address { + key "ip"; + status deprecated; + description + "The list of IPv6 addresses on the interface."; + + leaf ip { + type inet:ipv6-address-no-zone; + status deprecated; + description + "The IPv6 address on the interface."; + } + leaf prefix-length { + type uint8 { + range "0..128"; + } + mandatory true; + status deprecated; + description + "The length of the subnet prefix."; + } + leaf origin { + type ip-address-origin; + status deprecated; + description + "The origin of this address."; + } + leaf status { + type enumeration { + enum preferred { + description + "This is a valid address that can appear as the + destination or source address of a packet."; + } + enum deprecated { + description + "This is a valid but deprecated address that should + no longer be used as a source address in new + communications, but packets addressed to such an + address are processed as expected."; + } + enum invalid { + description + "This isn't a valid address, and it shouldn't appear + as the destination or source address of a packet."; + } + + enum inaccessible { + description + "The address is not accessible because the interface + to which this address is assigned is not + operational."; + } + enum unknown { + description + "The status cannot be determined for some reason."; + } + enum tentative { + description + "The uniqueness of the address on the link is being + verified. Addresses in this state should not be + used for general communication and should only be + used to determine the uniqueness of the address."; + } + enum duplicate { + description + "The address has been determined to be non-unique on + the link and so must not be used."; + } + enum optimistic { + description + "The address is available for use, subject to + restrictions, while its uniqueness on a link is + being verified."; + } + } + status deprecated; + description + "The status of an address. Most of the states correspond + to states from the IPv6 Stateless Address + Autoconfiguration protocol."; + reference + "RFC 4293: Management Information Base for the + Internet Protocol (IP) + - IpAddressStatusTC + RFC 4862: IPv6 Stateless Address Autoconfiguration"; + } + } + + list neighbor { + key "ip"; + status deprecated; + description + "A list of mappings from IPv6 addresses to + link-layer addresses. + This list represents the Neighbor Cache."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)"; + + leaf ip { + type inet:ipv6-address-no-zone; + status deprecated; + description + "The IPv6 address of the neighbor node."; + } + leaf link-layer-address { + type yang:phys-address; + status deprecated; + description + "The link-layer address of the neighbor node."; + } + leaf origin { + type neighbor-origin; + status deprecated; + description + "The origin of this neighbor entry."; + } + leaf is-router { + type empty; + status deprecated; + description + "Indicates that the neighbor node acts as a router."; + } + leaf state { + type enumeration { + enum incomplete { + description + "Address resolution is in progress, and the + link-layer address of the neighbor has not yet been + determined."; + } + enum reachable { + description + "Roughly speaking, the neighbor is known to have been + reachable recently (within tens of seconds ago)."; + } + enum stale { + description + "The neighbor is no longer known to be reachable, but + until traffic is sent to the neighbor no attempt + should be made to verify its reachability."; + } + enum delay { + description + "The neighbor is no longer known to be reachable, and + traffic has recently been sent to the neighbor. + Rather than probe the neighbor immediately, however, + delay sending probes for a short while in order to + give upper-layer protocols a chance to provide + reachability confirmation."; + } + enum probe { + description + "The neighbor is no longer known to be reachable, and + unicast Neighbor Solicitation probes are being sent + to verify reachability."; + } + } + status deprecated; + description + "The Neighbor Unreachability Detection state of this + entry."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 7.3.2"; + } + } + } + } +} diff --git a/radio/fhi_72/mplane/yang/models/o-ran-compression-factors.yang b/radio/fhi_72/mplane/yang/models/o-ran-compression-factors.yang new file mode 100644 index 0000000000..5816b5ed63 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/o-ran-compression-factors.yang @@ -0,0 +1,368 @@ +module o-ran-compression-factors { + yang-version 1.1; + namespace "urn:o-ran:compression-factors:1.0"; + prefix "o-ran-compression-factors"; + + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the module capabilities for + the O-RAN Radio Unit U-Plane configuration. + + Copyright 2020 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + revision "2020-08-10" { + description + "version 4.0.0 + + 1) supporting compression types per endpoint + 2) adding feature for configurable fs-offset for compression"; + + reference "ORAN-WG4.M.0-v04.00"; + } + + revision "2020-04-17" { + description + "version 3.0.0 + + 1) adding selective RE sending compression types"; + + reference "ORAN-WG4.M.0-v03.00"; + } + + revision "2019-07-03" { + description + "version 1.1.0 + + 1) changes related to compression bitwidth presentation"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + feature CONFIGURABLE-FS-OFFSET { + description + "Presence of this feature means that O-RU supports configurable fs-offset for compression."; + } + + grouping compression-method-grouping { + description + "Grouping for compression method."; + + leaf iq-bitwidth { + type uint8; + description + "Bitwidth to be used in compression"; + } + + leaf compression-method { + type enumeration { + enum NO_COMPRESSION { + description + "No compression will be used"; + } + enum BLOCK_FLOATING_POINT { + description + "Block floating point compression and decompression will be used"; + } + + enum BLOCK_SCALING { + description + "Block scaling compression and decompresion will be used"; + } + + enum U_LAW { + description + "u-Law compression and decompresion method will be used"; + } + + enum BEAMSPACE { + description + "Beamspace compression and decompression will be used"; + } + + enum MODULATION { + description + "Modulation compression and decompression will be used"; + } + enum BLOCK-FLOATING-POINT-SELECTIVE-RE-SENDING { + description + "block floating point with selective re sending + compression and decompression will be used"; + } + enum MODULATION-COMPRESSION-SELECTIVE-RE-SENDING { + description + "modulation compression with selective re sending + compression and decompression will be used"; + } + } + description + "Compresion method which can be supported by the O-RU"; + } + } + + grouping compression-formats { + description + "Grouping deicated to list compression formats as choice"; + + choice compression-format { + description + "Choice of compression format for particular element"; + + case no-compresison { + description "Compression for beam weights is not supported."; + } + case block-floating-point { + description "Block floating point compression and decompression is supported."; + + leaf exponent { + type uint8 { + range "4"; + } + description "Exponent bit width size in number of bits used when encoding in udCompParam."; + } + } + + case block-floating-point-selective-re-sending { + description + "Block floating point with selective re sending compression and decompression is supported."; + + leaf sres-exponent { + type uint8 { + range "4"; + } + description "Exponent bit width size in number of bits used when encoding in udCompParam."; + } + } + + case block-scaling { + description "Block scaling compression and decompresion is supported."; + leaf block-scalar { + type uint8; + description + "Common scaler for compressed PRB"; + } + } + + case u-law { + description "u-Law compression and decompresion method is supported."; + leaf comp-bit-width { + type uint8 { + range "0..15"; + } + description "Bit with for u-law compression"; + } + leaf comp-shift { + type uint8 { + range "0..15"; + } + description + "the shift applied to the entire PRB"; + } + } + + case beam-space-compression { + description "Beamspace compression and decompression is supported. Applies to beamforming weights only."; + leaf-list active-beam-space-coeficient-mask { + type uint8; + description + "active beamspace coefficient indices associated with the compressed beamforming vector"; + } + leaf block-scaler { + type uint8; + description + "Common scaler for compressed beamforming coefficients"; + } + } + + case modulation-compression { + description "Modulation compression and decompression is supported."; + leaf csf { + type uint8 { + range "0..1"; + } + description "Constallation shift flag"; + } + + leaf mod-comp-scaler { + type uint16 { + range "0..32767"; + } + description "Modulation compression scaler value."; + } + } + + case modulation-compression-selective-re-sending { + description "Modulation compression with selective re sending and decompression is supported."; + leaf sres-csf { + type uint8 { + range "0..1"; + } + description "Constallation shift flag"; + } + + leaf sres-mod-comp-scaler { + type uint16 { + range "0..32767"; + } + description "Modulation compression scaler value."; + } + } + + } + } + + grouping compression-params { + description + "Parameters to define compression"; + + leaf compression-type { + type enumeration { + enum STATIC { + description + "Indicates that static compression method will be used (both compression and IQ bitwidth)"; + } + enum DYNAMIC { + description + "Indicates that dynamic compression method will be used"; + } + } + mandatory true; + description + "Compression type that O-DU wants to be supported"; + } + +// *********** TO BE REMOVED *********** + leaf bitwidth { + when "../compression-type = 'STATIC'"; + type uint8; + status deprecated; + description + "Bitwidth to be used in compression. + This has since been replaced in M-Plane version + 2.0.0 with the iq-bitwidth schema node"; + } +// ************************************* + + uses compression-formats; + } + + grouping compression-parameters { + description + "Parameters used to define description type"; + + leaf iq-bitwidth { + type uint8; + description + "Bitwidth to be used in compression"; + } + + uses compression-formats; + } + + grouping format-of-iq-sample { + description + "Indicates module capabilities about IQ samples"; + + leaf dynamic-compression-supported { + type boolean; + + description + "Informs if radio supports dynamic compression method"; + } + + leaf realtime-variable-bit-width-supported { + type boolean; + + description + "Informs if O-RU supports realtime variable bit with"; + } + + list compression-method-supported { + uses compression-parameters; + + description + "List of supported compression methods by O-RU + Note: if O-RU supports different compression methods per endpoint + then please refer do endpoints to have information what + exactly is supported on a paticular endpoint"; + } + + leaf syminc-supported { + type boolean; + + description + "Informs if symbol number increment command in a C-Plane is + supported or not"; + } + + leaf regularization-factor-se-supported { + type boolean; + + description + "Informs if regularizationFactor in section type 5 is + supported(true) or not(false)"; + } + + leaf little-endian-supported { + type boolean; + default false; + + description + "All O-RUs support bigendian byte order. This node informs if module supports the + the optional capability for little endian byte order for C/U plane data flows. + + Note - little endian support does not invalidate bigendian support."; + } + } + + + grouping compression-details { + description ""; + + leaf iq-bitwidth { + type uint8; + description + "Bitwidth to be used in compression"; + } + + uses compression-params; + } +} diff --git a/radio/fhi_72/mplane/yang/models/o-ran-interfaces.yang b/radio/fhi_72/mplane/yang/models/o-ran-interfaces.yang new file mode 100644 index 0000000000..92587ce40c --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/o-ran-interfaces.yang @@ -0,0 +1,414 @@ +module o-ran-interfaces { + yang-version 1.1; + namespace "urn:o-ran:interfaces:1.0"; + prefix "o-ran-int"; + + + import ietf-inet-types { + prefix "inet"; + } + + import iana-if-type { + prefix "ianaift"; + } + + import ietf-interfaces { + prefix "if"; + } + + import ietf-ip { + prefix "ip"; + } + + import ietf-hardware { + prefix "hw"; + } + + import ietf-yang-types { + prefix "yang"; + } + + import iana-hardware { + prefix "ianahw"; + } + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the YANG definitions for managng the O-RAN + interfaces. + + Copyright 2020 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + revision "2020-04-17" { + description + "version 1.2.0 + + 1) updated descriptions to clarify operation when vlan-tagging is false"; + + reference "ORAN-WG4.M.0-v03.00"; + } + revision "2019-07-03" { + description + "version 1.1.0 + + 1) increasing max elements for user plane DSCP markings to 64 + 2) re-organizing layout to facilitate cross-WG adoption, whilst ensuring + nodes are syntactically and semantically equivalent"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + feature UDPIP-BASED-CU-PLANE { + description + "This feature indicates that the RU supports the UDP/IP based transport + for the CU plane."; + } + + feature ALIASMAC-BASED-CU-PLANE { + description + "This feature indicates that the RU supports the alias MAC address + based transport for the CU plane."; + } + + + typedef pcp { + type uint8 { + range "0..7"; + } + description + "Priority Code Point. PCP is a 3-bit field that refers to the + class of service applied to a VLAN tagged frame. The + field specifies a priority value between 0 and 7, these values + can be used by quality of service (QoS) to prioritize + different classes of traffic."; + reference + "IEEE 802.1Q-2014: Virtual Bridged Local Area Networks"; + } + + grouping cos-marking { + description + "Configuration data for CU Plane ethernet CoS marking. + This grouping is only applicable to an interface when vlan-tagging is + set to TRUE for that interface. In other cases, it may be ignored."; + container class-of-service { + description + "CoS Configuration"; + leaf u-plane-marking { + type pcp; + default 7; + description + "Marking used for default u-plane flows. + 7 represents highest priority for u-plane marking"; + } + leaf c-plane-marking { + type pcp; + default 7; + description "7 represents highest priority for c-plane marking"; + } + leaf m-plane-marking { + type pcp; + default 2; + description "2 represents highest excellent effort for m-plane marking"; + } + leaf s-plane-marking { + type pcp; + default 7; + description "7 represents highest priority for s-plane marking"; + } + leaf other-marking { + type pcp; + default 1; + description "1 represents best effort for other marking"; + } + list enhanced-uplane-markings{ + key "up-marking-name"; + max-elements 4; + description + "list of mappings for enhanced (non-default) u-plane markings"; + leaf up-marking-name { + type string; + description "The name of the marking"; + } + leaf enhanced-marking { + type pcp; + description "the enhanced u-plane marking"; + } + } + } + } + + grouping dscp-marking { + description + "Configuration data for CU Plane DSCP marking"; + container diffserv-markings { + description + "DSCP Configuration"; + leaf u-plane-marking { + type inet:dscp; + default 46; + description + "Marking used for default u-plane flows. + 46 represents expedited forwarding"; + } + leaf c-plane-marking { + type inet:dscp; + default 46; + description "46 represents expedited forwarding"; + } + leaf s-plane-marking { + type inet:dscp; + default 46; + description "46 represents expedited forwarding"; + } + leaf other-marking { + type inet:dscp; + default 0; + description "0 represents best effort forwarding"; + } + list enhanced-uplane-markings{ + key up-marking-name; + max-elements 64; + description + "list of mappings for enhanced (non-default) u-plane markings"; + leaf up-marking-name { + type string; + description "The name of the marking"; + } + leaf enhanced-marking { + type inet:dscp; + description "the enhanced u-plane marking"; + } + } + } + } + +// Cross Working Group Augmentations Follow + +// Cross Working Group augmentations for basic Ethernet leafs + + augment "/if:interfaces/if:interface" { + when "if:type = 'ianaift:ethernetCsmacd'" { + description "Applies to Ethernet interfaces"; + } + description + "Augment the interface model with parameters for + base Ethernet interface"; + + leaf l2-mtu { + type uint16 { + range "64 .. 65535"; + } + units bytes; + default 1500; + description + "The maximum size of layer 2 frames that may be transmitted + or received on the interface (excluding any FCS overhead). + For Ethernet interfaces it also excludes the + 4-8 byte overhead of any known (i.e. explicitly matched by + a child sub-interface) 801.1Q VLAN tags."; + } + leaf vlan-tagging { + type boolean; + default true; + description + "Indicates if VLAN tagging is used. + Default true is used to enable equipment to autonomously discover that + it is connected to a trunk port. + + This may be set to false, for example, when the O-RU is directly + connected to the O-DU. In such cases, native Ethernet frames may be + used across the O-RAN interface, i.e., any PCP markings defined + in the cos-markings grouping are NOT used by the O-RU and any default + value or configured value using those leafs may be ignored by the O-RAN + equipment."; + } + uses cos-marking; + } + +// Cross Working Group augmentation for l2vlan interfaces for VLAN definition + + augment "/if:interfaces/if:interface" { + when "if:type = 'ianaift:l2vlan'"; + description "augments for VLAN definition"; + leaf base-interface { + type if:interface-ref; + must "/if:interfaces/if:interface[if:name = current()]" + + "/o-ran-int:vlan-tagging = 'true'" { + description + "The base interface must have VLAN tagging enabled."; + } + description + "The base interface for the VLAN sub-interafce."; + } + leaf vlan-id { + type uint16 { + range "1..4094"; + } + description + "The VLAN-ID."; + } + } + +// Cross Working Group augmention for both ethernetCsmacd and l2vlan interfaces + + augment "/if:interfaces/if:interface" { + when "(if:type = 'ianaift:ethernetCsmacd') or + (if:type = 'ianaift:l2vlan')" { + description "Applies to ethernetCsmacd and l2vlan interfaces"; + } + description + "Augment the interface model with parameters for all + both ethernetCsmacd and l2vlan interfaces."; + leaf last-cleared { + type yang:date-and-time; + config false; + description + "Timestamp of the last time the interface counters were + cleared."; + } + } + +// Cross Working Group augmention to ietf-ip covering DSCP for M-Plane + +augment "/if:interfaces/if:interface/ip:ipv4" { + description "augments for IPv4 based M-Plane transport"; + leaf m-plane-marking { + type inet:dscp; + default 18; + description "18 represents AF21 or 'immediate traffic'"; + } +} +augment "/if:interfaces/if:interface/ip:ipv6" { + description "augments for IPv6 based M-Plane transport"; + leaf m-plane-marking { + type inet:dscp; + default 18; + description "18 represents AF21 or 'immediate traffic'"; + } +} + +// WG4 Specific Augmentations Follow + +// WG4 Augmentation for basic Ethernet leafs + + augment "/if:interfaces/if:interface" { + if-feature ALIASMAC-BASED-CU-PLANE; + when "if:type = 'ianaift:ethernetCsmacd'" { + description + "Applies to WG4 Ethernet interfaces for alias MAC based CU-Plane"; + } + description + "Augment the interface model with parameters for + base Ethernet interface"; + + leaf-list alias-macs { + type yang:mac-address; + description + "Augments interfaces with range of alias MAC addresses."; + } + } + +// WG4 Augmention for both ethernetCsmacd and l2vlan interfaces + + augment "/if:interfaces/if:interface" { + when "(if:type = 'ianaift:ethernetCsmacd') or + (if:type = 'ianaift:l2vlan')" { + description "Applies to ethernetCsmacd and l2vlan interfaces"; + } + description + "Augment the interface model with parameters for all + both ethernetCsmacd and l2vlan interfaces."; + leaf mac-address { + type yang:mac-address; + description + "The MAC address of the interface."; + } + container port-reference { + description + "a port reference used by other O-RAN modules"; + leaf port-name { + type leafref { + path '/hw:hardware/hw:component/hw:name'; + } + must "derived-from-or-self(deref(current())/../hw:class, 'ianahw:port')"; +// TAKE NOTE - depending on version of pyang, this may generate various +// warnings, e.g., warning: XPath for "port-name" does not exist + description + "O-RAN interfaces use a reference to a physical port component. + + In this case, the component name referenced must be of class type + port, i.e., when /hw:hardware/hw:component/hw:class is derived from + ianahw:port"; + } + leaf port-number { + type uint8; + description + "A number allocated by the server which identifies a port. + Port number value is 0 to N-1 where N is number of ports + in the device. + + This value is fixed for the lifetime of the equipment, i.e., cannot be + changed during equipment reboots."; + } + } + } + +// WG4 specific augmention to ietf-ip covering DSCP for CUS Plane + + augment "/if:interfaces/if:interface/ip:ipv4" { + if-feature UDPIP-BASED-CU-PLANE; + description "augments for IPv4 based CUS transport"; + uses dscp-marking; + } + augment "/if:interfaces/if:interface/ip:ipv6" { + if-feature UDPIP-BASED-CU-PLANE; + description "augments for IPv6 based CUS transport"; + uses dscp-marking; + } + +// Other Working Group Specific Augmentations Follow Here + + + rpc reset-interface-counters { + description + "Management plane triggered restart of the interface counters."; + } +} diff --git a/radio/fhi_72/mplane/yang/models/o-ran-module-cap.yang b/radio/fhi_72/mplane/yang/models/o-ran-module-cap.yang new file mode 100644 index 0000000000..e726d57e72 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/o-ran-module-cap.yang @@ -0,0 +1,840 @@ +module o-ran-module-cap { + yang-version 1.1; + namespace "urn:o-ran:module-cap:1.0"; + prefix "o-ran-module-cap"; + + import o-ran-compression-factors { + prefix "cf"; + revision-date 2020-08-10; + } + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the module capabilities for + the O-RAN Radio Unit. + + Copyright 2020 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + revision "2020-08-10" { + description + "version 4.0.0 + + 1) added RO capability to expose O-RU's ability to support udCompLen record in U-Plane section header fields + 2) feature indicating support for static PRACH configuration introduced + 3) feature indicating support for static SRS configuration introduced + 4) feature indicating support for TDD pattern configuration introduced + 5) backward compatible change to introduce new O-RU's features related + to Section Description Priority to serve for CUS-Plane C"; + + reference "ORAN-WG4.M.0-v04.00"; + } + + revision "2020-04-17" { + description + "version 3.0.0 + + 1) Adding optional little endian support + 2) Added support for Dynamic Spectrum Sharing feature + 3) Enable number-of-ru-ports to be different between dl and ul + 4) Enable regularizationFactor to be signalled outside of section type 6 + 5) Enable PRACH preamble formats supported to be signalled by O-RU + 6) adding support for selective RE sending + 7) supporting new section extension for grouping multiple ports + 8) signalling to enable O-RU to ndicate is requires unique ecpri sequence id + for eAxC_IDs serving for UL and DL for the same carrier component"; + + reference "ORAN-WG4.M.0-v03.00"; + } + + revision "2019-07-03" { + description + "version 1.1.0 + + 1) backward compatible change to introduce new RW leafs for use in + constraints in uplane-config and laa models. + 2) removing unnecessary relations to band 46 in uplink"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + feature LAA { + description + "Indicates that the Radio Unit supports LAA."; + } + + feature EAXC-ID-GROUP-SUPPORTED { + description + "indicates that the Radio Unit supports EAXC-ID-GROUP-SUPPORTED."; + } + + feature TRANSPORT-FRAGMENTATION { + description + "This leaf is used to indicate whether the O-RU supports O-RAN Radio Transport Fragmentation"; + } + + feature DSS_LTE_NR { + description + "Indicates that the Radio Unit supports Dynamic Spectrum Sharing between LTE and NR."; + } + + feature PRACH-STATIC-CONFIGURATION-SUPPORTED { + description + "This leaf is used to indicate O-RU's support for configuration of PRACH (Physical Random Access Channel) pattern in the static manner, so that PRACH U-Plane traffic can be processed by RU without receiving C-Plane messages conveying the PRACH configuration."; + } + + feature SRS-STATIC-CONFIGURATION-SUPPORTED { + description + "This leaf is used to indicate O-RU's support for configuration of SRS (Sounding Reference Signal Channel) pattern in the static manner, so that SRS U-Plane traffic can be processed by RU without receiving C-Plane messages conveying the SRS configuration."; + } + + feature CONFIGURABLE-TDD-PATTERN-SUPPORTED { + description + "This leaf is used to indicate O-RU's support for configurable TDD pattern."; + } + + typedef sub-band-string { + type string { + pattern [ABCD]; + } + description "Sub bands definition"; + } + + typedef scs-config-type { + type enumeration { + enum KHZ_15 { + value 0; + description + "15kHz sub carrier spacing"; + } + enum KHZ_30 { + value 1; + description + "30kHz sub carrier spacing"; + } + enum KHZ_60 { + value 2; + description + "60kHz sub carrier spacing"; + } + enum KHZ_120 { + value 3; + description + "120kHz sub carrier spacing"; + } + enum KHZ_240 { + value 4; + description + "240kHz sub carrier spacing"; + } + enum KHZ_1_25 { + value 12; + description + "1,25kHz sub carrier spacing"; + } + enum KHZ_3_75 { + value 13; + description + "3.75kHz sub carrier spacing"; + } + enum KHZ_5 { + value 14; + description + "5kHz sub carrier spacing"; + } + enum KHZ_7_5 { + value 15; + description + "7.5kHz sub carrier spacing"; + } + } + + description + "Scs configuration type definition"; + } + + grouping compression-method-grouping { + description + "Grouping for compression method."; + + leaf compression-method { + type enumeration { + enum BLOCK_FLOATING_POINT { + description + "Block floating point compression and decompression will be used"; + } + + enum BLOCK_SCALING { + description + "Block scaling compression and decompresion will be used"; + } + + enum U_LAW { + description + "u-Law compression and decompresion method will be used"; + } + + enum BEAMSPACE { + description + "Beamspace compression and decompression will be used"; + } + + enum MODULATION { + description + "Modulation compression and decompression will be used"; + } + + enum BLOCK-FLOATING-POINT-SELECTIVE-RE-SENDING { + description + "block floating point with selective re sending + compression and decompression will be used"; + } + enum MODULATION-COMPRESSION-SELECTIVE-RE-SENDING { + description + "modulation compression with selective re sending + compression and decompression will be used"; + } + } + description + "Compresion method which can be supported by the O-RU. + An O-RU may further refine the applicability of compression + methods per endpoint using o-ran-uplane-conf.yang model"; + } + } + + grouping sub-band-max-min-ul-dl-frequency { + description + "Grouping for defining max and min supported frequency - dl and ul."; + + leaf max-supported-frequency-dl { + type uint64; + description + "This value indicates Maximum supported downlink frequency in the + LAA subband. Value unit is Hz."; + } + + leaf min-supported-frequency-dl { + type uint64; + description + "This value indicates Minimum supported downlink frequency in the + LAA subband. Value unit is Hz."; + } + } + + grouping format-of-iq-sample { + description + "Indicates module capabilities about IQ samples"; + + leaf dynamic-compression-supported { + type boolean; + + description + "Informs if radio supports dynamic compression method"; + } + + leaf realtime-variable-bit-width-supported { + type boolean; + + description + "Informs if O-RU supports realtime variable bit with"; + } + + list compression-method-supported { + uses cf:compression-details; + + leaf-list fs-offset { + if-feature cf:CONFIGURABLE-FS-OFFSET; + type uint8; + default 0; + description + "List of fs offset values supported with this IQ format / compression method; + fs-offset adjusts FS (full scale) value of IQ format relative to FS derived from unmodified IQ format. + Please refer to CU-Plane specification for details"; + } + + description + "List of supported compression methods by O-RU + Note: if O-RU supports different compression methods per endpoint + then please refer to endpoints to have information what + exactly is supported on paticular endpoint"; + } + + leaf variable-bit-width-per-channel-supported { + when "/module-capability/ru-capabilities/format-of-iq-sample/realtime-variable-bit-width-supported = 'true'"; + type boolean; + + description + "Informs if variable bit width per channel is supported or not"; + } + + leaf syminc-supported { + type boolean; + + description + "Informs if symbol number increment command in a C-Plane is + supported or not"; + } + + leaf regularization-factor-se-supported { + type boolean; + + description + "Informs if regularizationFactor in section type 5 is + supported(true) or not(false)"; + } + + leaf little-endian-supported { + type boolean; + default false; + + description + "All O-RUs support bigendian byte order. This node informs if module supports the + the optional capability for little endian byte order for C/U plane data flows. + + Note - little endian support does not invalidate bigendian support."; + } + + } + + grouping scs-a-b { + description + "Grouping for scs-a and scs-b"; + leaf scs-a{ + type scs-config-type; + description + "Sub-carrier spacing configuration"; + } + leaf scs-b{ + type scs-config-type; + description + "Sub-carrier spacing configuration"; + } + } + + grouping ul-mixed-num-required-guard-rbs { + description + "Required number of guard resource blocks for the combination of + subcarrier spacing values for uplink"; + uses scs-a-b; + leaf number-of-guard-rbs-ul{ + type uint8; + description + "This value indicates the required number of guard resource blocks + between the mixed numerologies, the RB using scs-a and the RB + using scs-b. It's number is based on scs-a"; + } + } + + grouping dl-mixed-num-required-guard-rbs { + description + "Required number of guard resource blocks for the combination of + subcarrier spacing values for uplink"; + uses scs-a-b; + leaf number-of-guard-rbs-dl{ + type uint8; + description + "This value indicates the required number of guard resource blocks + between the mixed numerologies, the RB using scs-a and the RB + using scs-b. It's number is based on scs-a"; + } + } + + grouping ru-capabilities { + description + "Structure representing set of capabilities."; + + leaf ru-supported-category { + type enumeration { + enum CAT_A { + description + "Informs that precoding is not supported in O-RU"; + } + enum CAT_B { + description + "Informs that precoding is supported in O-RU"; + } + } + + description + "Informs about which category O-RU supports"; + } + + leaf number-of-ru-ports { + type uint8; + status deprecated; + description + "Assuming all endpoints support time-managed traffic AND non-time-managed traffic (choice is as per configuration) + - the number of O-RU ports is the product of number of spatial streams (leaf number-of-spatial-streams) and number of numerologies O-RU supports. + For example, if the number of spatial streams is 4 then the number of O-RU ports is 8 when PUSCH and PRACH are processed in the different endpoints. + In case there are specific endpoints that support non-time-managed traffic only + - the number of O-RU ports calculated with above mentioned equation is extended by number of endpoints supporting only non-time-managed traffic."; + } + leaf number-of-ru-ports-ul { + type uint8; + description + "Assuming all endpoints support time-managed traffic AND non-time-managed traffic (choice is as per configuration) + - the number of O-RU ports for uplink is the product of number of spatial streams (leaf number-of-spatial-streams) and number of numerologies O-RU supports. + For example, if the number of spatial streams is 4 then the number of O-RU ports is 8 when PUSCH and PRACH are processed in the different endpoints. + In case there are specific endpoints that support non-time-managed traffic only + - the number of O-RU ports calculated with above mentioned equation is extended by number of endpoints supporting only non-time-managed traffic."; + } + leaf number-of-ru-ports-dl { + type uint8; + description + "Assuming all endpoints support time-managed traffic AND non-time-managed traffic (choice is as per configuration) + - the number of O-RU ports for downlink is the product of number of spatial streams (leaf number-of-spatial-streams) and number of numerologies O-RU supports. + For example, if the number of spatial streams is 4 then the number of O-RU ports is 8 when SSB and non-SSB are processed in the different endpoints. + In case there are specific endpoints that support non-time-managed traffic only + - the number of O-RU ports calculated with above mentioned equation is extended by number of endpoints supporting only non-time-managed traffic."; + } + + leaf number-of-spatial-streams { + type uint8; + description + "This value indicates the number of spatial streams supported at O-RU for DL and UL. + For DL, it is same as the number of antenna ports specified in 3GPP TS38.214, Section 5.2 and 3GPP TS36.213, Section 5.2."; + } + + leaf max-power-per-pa-antenna { + type decimal64{ + fraction-digits 4; + } + description + "This value indicates Maximum Power per PA per antenna. Value unit is dBm."; + } + + leaf min-power-per-pa-antenna { + type decimal64{ + fraction-digits 4; + } + description + "This value indicates Minimum Power per PA per antenna. Value unit is dBm."; + } + + leaf fronthaul-split-option { + type uint8 { + range "7"; + } + description + "This value indicates the Fronthaul Split Option, i.e., 2 or 7 in this release."; + } + + container format-of-iq-sample { + description + "Indicates module capabilities about IQ samples"; + + uses format-of-iq-sample; + } + + list ul-mixed-num-required-guard-rbs { + key "scs-a scs-b"; + description + "List of required number of guard resource blocks + for the combination of subcarrier spacing values for downlink"; + + uses ul-mixed-num-required-guard-rbs; + } + list dl-mixed-num-required-guard-rbs { + key "scs-a scs-b"; + description + "List of required number of guard resource blocks + for the combination of subcarrier spacing values for uplink"; + + uses dl-mixed-num-required-guard-rbs; + } + + leaf energy-saving-by-transmission-blanks { + type boolean; + mandatory true; + description + "Parameter informs if unit supports energy saving by transmission blanking"; + } + container eaxcid-grouping-capabilities { + if-feature o-ran-module-cap:EAXC-ID-GROUP-SUPPORTED; + description + "a container with parameters for eaxcid grouping"; + leaf max-num-tx-eaxc-id-groups { + type uint8; + description + "Maximum number of configurable tx-eaxc-id-group supported by O-RU."; + } + leaf max-num-tx-eaxc-ids-per-group { + type uint8; + description + "Maximum number of member-tx-eaxc-id in single tx-eaxc-id-group supported by O-RU."; + } + leaf max-num-rx-eaxc-id-groups { + type uint8; + description + "the maximum number of groups with the eAxC IDs those are assigned to low-level-rx-links."; + } + leaf max-num-rx-eaxc-ids-per-group { + type uint8; + description + "the maximum number of eAxC IDs per rx-eaxc-id-group."; + } + } + + leaf dynamic-transport-delay-management-supported { + type boolean; + mandatory true; + description + "Parameter informs if unit supports dynamic transport delay management through eCPRI Msg 5"; + } + + leaf support-only-unique-ecpri-seqid-per-eaxc { + type boolean; + default false; + description + "Parameter informs if O-RU expects unique ecpri sequence id for eAxC_IDs serving + for UL and DL for the same carrier component. + + Note: If this is set to TRUE, the O-DU can decide to either use different eAxC_IDs for UL and + DL or can generate unique sequence ID per eAxC_ID. + + TAKE NOTE: This leaf is backwards compatible from an O-RU persepctive BUT an O-RU that + sets this leaf to TRUE may result in incompatibilities when operating with an O-DU + designed according to the O-RAN CUS-Plane Specification v02.00, e.g., if the O-DU is + incapable of using different eAxC values between UL and DL"; + } + + container coupling-methods { + description + "O-RU's capabilities related to supported C-Plane and U-Plane coupling methods"; + + leaf coupling-via-frequency-and-time { + type boolean; + description + "Coupling via frequency and time; see methods of coupling of C-plane and U-plane in CUS-Plane specification"; + } + + leaf coupling-via-frequency-and-time-with-priorities { + type boolean; + description + "Coupling via Frequency and time with priorities; see methods of coupling of C-plane and U-plane in CUS-Plane specification. + Note: If coupling-via-frequency-and-time-with-priorities is 'true' then coupling-via-frequency-and-time shall also be 'true'."; + } + } + + leaf ud-comp-len-supported { + type boolean; + description + "This property informs if O-RU supports optional field udCompLen in U-Plane messages. + Only in case this leaf is present and its value is TRUE, O-RU supports U-Plane messages + containing udCompLen field in section header."; + } + } + + grouping sub-band-info { + description "container for collection of leafs for LAA subband 46"; + list sub-band-frequency-ranges { + key sub-band; + description "frequency information on a per sub-band basis"; + leaf sub-band { + type sub-band-string; + description "Sub band when band 46"; + } + uses sub-band-max-min-ul-dl-frequency; + } + leaf number-of-laa-scarriers { + type uint8; + description + "This value indicates the number of LAA secondary carriers supported at O-RU."; + } + + leaf maximum-laa-buffer-size { + type uint16; + description + "Maximum O-RU buffer size in Kilobytes (KB) per CC. This parameter is + needed at the O-DU to know how much data can be sent in advance + and stored at the O-RU to address the LBT uncertainity."; + } + + leaf maximum-processing-time { + type uint16; + units microseconds; + description + "Maximum O-RU Processing time in microseconds at the O-RU to handle the + received/transmitted packets from/to the O-DU. This parameter is + needed at the O-DU to determine the time where it needs to send + the data to the O-RU."; + } + + leaf self-configure { + type boolean; + description "This value indicates that the O-RU can manage the contention window locally. "; + } + } + + grouping support-for-dl { + description + "Grouping for DL specific parameters"; + + leaf max-supported-frequency-dl { + type uint64; + description + "This value indicates Maximum supported downlink frequency. Value unit is Hz."; + } + + leaf min-supported-frequency-dl { + type uint64; + description + "This value indicates Minimum supported downlink frequency. Value unit is Hz."; + } + + leaf max-supported-bandwidth-dl { + type uint64; + description + "This value indicates Maximum total downlink bandwidth in module. Value unit is Hz."; + } + + leaf max-num-carriers-dl { + type uint32; + description + "This value indicates Maximum number of downlink carriers in module."; + } + + leaf max-carrier-bandwidth-dl { + type uint64; + description + "This value indicates Maximum bandwidth per downlink carrier. Value unit is Hz."; + } + + leaf min-carrier-bandwidth-dl { + type uint64; + description + "This value indicates Minimum bandwidth per downlink carrier. Value unit is Hz."; + } + + leaf-list supported-technology-dl { + type enumeration{ + enum LTE { + description "LTE is supported in DL path."; + } + enum NR { + description "NR is supported in DL path."; + } + enum DSS_LTE_NR { + if-feature DSS_LTE_NR; + description + "DSS is supported in the DL, which implicitly means LTE and NR are also + BOTH supported in the DL."; + } + } + min-elements 1; + description + "This list provides information regarding technologies supported in DL path"; + } + } + + grouping support-for-ul { + description + "Grouping for UL specific parameters"; + + leaf max-supported-frequency-ul { + type uint64; + description + "This value indicates Maximum supported uplink frequency. Value unit is Hz."; + } + + leaf min-supported-frequency-ul { + type uint64; + description + "This value indicates Minimum supported uplink frequency. Value unit is Hz."; + } + + leaf max-supported-bandwidth-ul { + type uint64; + description + "This value indicates Maximum total uplink bandwidth in module. Value unit is Hz."; + } + + leaf max-num-carriers-ul { + type uint32; + description + "This value indicates Maximum number of uplink carriers in module."; + } + + leaf max-carrier-bandwidth-ul { + type uint64; + description + "This value indicates Maximum bandwidth per uplink carrier. Value unit is Hz."; + } + + leaf min-carrier-bandwidth-ul { + type uint64; + description + "This value indicates Minimum bandwidth per uplink carrier. Value unit is Hz."; + } + + leaf-list supported-technology-ul { + type enumeration{ + enum LTE { + description "LTE is supported in UL path."; + } + enum NR { + description "NR is supported in UL path."; + } + enum DSS_LTE_NR { + if-feature DSS_LTE_NR; + description + "DSS is supported in the UL, which implicitly means LTE and NR are also + BOTH supported in the UL."; + } + } + min-elements 1; + description + "This list provides information regarding technologies supported in UL path"; + } + } + + grouping band-capabilities { + description + "Capabilities that are needed to be defined per each band"; + + leaf band-number { + type uint16; + description + "Band number"; + } + + container sub-band-info { + when "../band-number = '46'"; + if-feature "o-ran-module-cap:LAA"; + description "container for collection of leafs for LAA subband 46"; + uses sub-band-info; + } + + uses support-for-dl; + uses support-for-ul; + + leaf max-num-component-carriers { + type uint8; + description "maximum number of component carriers supported by the O-RU"; + } + + leaf max-num-bands { + type uint16; + description "maximum number of bands supported by the O-RU"; + } + + leaf max-num-sectors { + type uint8; + description "maximum number of sectors supported by the O-RU"; + } + + leaf max-power-per-antenna { + type decimal64{ + fraction-digits 4; + } + description + "This value indicates Maximum Power per band per antenna. Value unit is dBm."; + } + + leaf min-power-per-antenna { + type decimal64{ + fraction-digits 4; + } + description + "This value indicates Minimum Power per band per antenna. Value unit is dBm."; + } + + leaf codebook-configuration_ng { + type uint8; + description + "This parameter informs the precoder codebook_ng that are used for precoding"; + } + + leaf codebook-configuration_n1 { + type uint8; + description + "This parameter informs the precoder codebook_n1 that are used for precoding"; + } + + leaf codebook-configuration_n2 { + type uint8; + description + "This parameter informs the precoder codebook_n2 that are used for precoding"; + } + } + + container module-capability { + + description + "module capability object responsible for providing module capability."; + + container ru-capabilities { + config false; + description + "Structure representing set of capabilities."; + + uses ru-capabilities; + } + + list band-capabilities { + key band-number; + config false; + description + "Capabilities that are needed to be defined per each band"; + + uses band-capabilities; + } + container rw-sub-band-info { + if-feature "o-ran-module-cap:LAA"; + description "config true leafrefs for use as constraints for config true leafs"; + leaf rw-number-of-laa-scarriers { + type leafref { + path "/module-capability/band-capabilities/sub-band-info/number-of-laa-scarriers"; + require-instance false; + } + description + "This value indicates the number of LAA secondary carriers supported at O-RU."; + } + leaf rw-self-configure { + type leafref { + path "/module-capability/band-capabilities/sub-band-info/self-configure"; + require-instance false; + } + description + "This value indicates that the O-RU can manage the contention window locally."; + } + } + } +} diff --git a/radio/fhi_72/mplane/yang/models/o-ran-processing-element.yang b/radio/fhi_72/mplane/yang/models/o-ran-processing-element.yang new file mode 100644 index 0000000000..fc930a0a81 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/o-ran-processing-element.yang @@ -0,0 +1,362 @@ +module o-ran-processing-element { + yang-version 1.1; + namespace "urn:o-ran:processing-element:1.0"; + prefix "o-ran-elements"; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix "inet"; + } + + import ietf-interfaces { + prefix "if"; + } + + import ietf-ip { + prefix "ip"; + } + + import o-ran-interfaces { + prefix "o-ran-int"; + } + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the YANG definitions for mapping of transport flows to + processing elements. Three options are supported: + i) virtual MAC based mapping + ii) MAC addrress + VLAN-ID based mapping + iii) UDP/IP based mapping + + Copyright 2020 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + revision "2020-04-17" { + description + "version 3.0.0 + + 1) added new enum SHARED-CELL-ETH-INTERFACE in + transport-session-type and new containers north-eth-flow and + south-eth-flow to enable Shared cell scenario."; + + reference "ORAN-WG4.M.0-v03.00"; + } + + revision "2019-07-03" { + description + "version 1.1.0 + + 1) added new leaf to enable O-RU to report the maximum number of + transport flows it can support, e.g., due to restrictions on number + of VLAN-IDs when ethernet type transport is used."; + + reference "ORAN-WG4.M.0-v01.00"; + } + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + feature SHARED_CELL { + description + "Presence of feature indicates that this O-RU is capable to support + shared cell."; + } +// groupings + + grouping pe-group { + leaf maximum-number-of-transport-flows { + type uint16 { + range "1..4094"; + } + config false; + default 4094; + description + "The maximum number of transport flows that can be supported by an O-RU"; + } + leaf transport-session-type { + type enumeration { + enum ETH-INTERFACE { + description "VLAN based CUS Transport "; + } + enum UDPIP-INTERFACE { + description "UDP/IP based CUS Transport "; + } + enum ALIASMAC-INTERFACE{ + description "Alias MAC address based CUS Transport "; + } + enum SHARED-CELL-ETH-INTERFACE { + if-feature "SHARED_CELL"; + description "VLAN based CUS Transport used for Shared Cell scenario"; + } + } + default ETH-INTERFACE; + description + "the type of transport session used for identifying different processing + elements"; + } + container enhanced-uplane-mapping { + presence "indicates that enhanced uplane mapping is used"; + description "a mapping table for enhanced user plane marking"; + list uplane-mapping { + key "up-marking-name"; + description + "a mapping between up-link name and o-ran-interfaces:up-marking-name"; + leaf up-marking-name { + type string; + description "a unique up marking name that is used for enhanced up marking"; + } + choice up-markings { + description + "U-Plane markings"; + case ethernet { + when "(../../transport-session-type = 'ALIASMAC-INTERFACE') or + (../../transport-session-type = 'ETH-INTERFACE') or + (../../transport-session-type = 'SHARED-CELL-ETH-INTERFACE')"; + leaf up-cos-name { + type leafref { + path "/if:interfaces/if:interface/o-ran-int:class-of-service/o-ran-int:enhanced-uplane-markings/o-ran-int:up-marking-name"; + } + description "the Ethernet U-plane transport marking as defined in o-ran-interfaces"; + } + } + case ipv4 { + when "(../../transport-session-type = 'UDPIP-INTERFACE')"; + leaf upv4-dscp-name { + if-feature o-ran-int:UDPIP-BASED-CU-PLANE; + type leafref { + path "/if:interfaces/if:interface/ip:ipv4/o-ran-int:diffserv-markings/o-ran-int:enhanced-uplane-markings/o-ran-int:up-marking-name"; + } + description "the IPv4 U-plane transport marking as defined in o-ran-interfaces"; + } + } + case ipv6 { + when "(../../transport-session-type = 'UDPIP-INTERFACE')"; + leaf upv6-dscp-name { + if-feature o-ran-int:UDPIP-BASED-CU-PLANE; + type leafref { + path "/if:interfaces/if:interface/ip:ipv6/o-ran-int:diffserv-markings/o-ran-int:enhanced-uplane-markings/o-ran-int:up-marking-name"; + } + description "the IPv6 U-plane transport marking as defined in o-ran-interfaces"; + } + } + } + } + } + list ru-elements { + key "name"; + description + "the list of transport definitions for each processing element"; + leaf name { + type string { + length "1..255"; + } + description + "A name that is unique across the O-RU that identifies a processing + element instance. + + This name may be used in fault management to refer to a fault source + or affected object"; + } + container transport-flow { + description + "container for the transport-flow used for CU plane"; + leaf interface-name { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + description "the interface name "; + } + container aliasmac-flow { + when "../../../transport-session-type = 'ALIASMAC-INTERFACE'"; + if-feature o-ran-int:ALIASMAC-BASED-CU-PLANE; + description "leafs for virtual mac type data flows"; + leaf ru-aliasmac-address { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:alias-macs"; + } + mandatory true; + description + "O-RU's alias MAC address used for alias MAC based flow"; + } + leaf vlan-id { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:vlan-id"; + } + description + "O-RU's VLAN-ID used for alias MAC based flow"; + } + leaf o-du-mac-address { + type yang:mac-address; + mandatory true; + description + "O-DU's MAC address used for alias MAC based flow"; + } + } + container eth-flow { + when "../../../transport-session-type = 'ETH-INTERFACE'"; + description "leafs for mac + vlan-id type data flows"; + leaf ru-mac-address { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:mac-address"; + } + mandatory true; + description + "O-RU's MAC address used for Ethernet based flow"; + } + leaf vlan-id { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:vlan-id"; + } + mandatory true; + description + "O-RU's VLAN-ID used for Ethernet based flow"; + } + leaf o-du-mac-address { + type yang:mac-address; + mandatory true; + description + "O-DU's MAC address used for Ethernet based flow"; + } + } + container udpip-flow { + when "../../../transport-session-type = 'UDPIP-INTERFACE'"; + description "leafs for UDP/IP type data flows"; + choice address { + leaf ru-ipv4-address { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/ip:ipv4/ip:address/ip:ip"; + } + description "O-RU's IPv4 address"; + } + leaf ru-ipv6-address { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/ip:ipv6/ip:address/ip:ip"; + } + description "O-RU's IPv6 address"; + } + mandatory true; + description "choice of O-RU IPv4 or IPv6 address"; + } + leaf o-du-ip-address { + type inet:ip-address; + mandatory true; + description "O-DU's IPv address"; + } + leaf ru-ephemeral-udp-port { + type inet:port-number; + mandatory true; + description + "ephemeral port used by O-RU"; + } + leaf o-du-ephemeral-udp-port { + type inet:port-number; + mandatory true; + description + "ephemeral port used by O-DU"; + } + leaf ecpri-destination-udp { + type inet:port-number; + mandatory true; + description "the well known UDP port number used by eCPRI"; + // fixme - add in a default when allocated by IANA + } + } + container north-eth-flow { + when "../../../transport-session-type = 'SHARED-CELL-ETH-INTERFACE'"; + if-feature "SHARED_CELL"; + description "leafs for mac + vlan-id type data flows"; + leaf ru-mac-address { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:mac-address"; + } + description + "O-RU's MAC address used for Ethernet based flow"; + } + leaf vlan-id { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:vlan-id"; + } + description + "O-RU's VLAN-ID used for Ethernet based flow"; + } + leaf north-node-mac-address { + type yang:mac-address; + description + "North-node's MAC address used for Ethernet based flow"; + } + } + container south-eth-flow { + when "../../../transport-session-type = 'SHARED-CELL-ETH-INTERFACE'"; + if-feature "SHARED_CELL"; + description "leafs for mac + vlan-id type data flows"; + leaf ru-mac-address { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:mac-address"; + } + description + "O-RU's MAC address used for Ethernet based flow"; + } + leaf vlan-id { + type leafref { + path "/if:interfaces/if:interface[if:name = current()/../../interface-name]/o-ran-int:vlan-id"; + } + description + "O-RU's VLAN-ID used for Ethernet based flow"; + } + leaf south-node-mac-address { + type yang:mac-address; + description + "south-node's MAC address used for Ethernet based flow"; + } + } + } + } + } + +// top level container + + container processing-elements { + description + "a model defining the mapping between transport flows and arbitrary + O-RAN processing elements. A processing element may be then defined for + handling connectivity or delay procedures, or defined with a corresponding + eaxcid for CU plane operations"; + uses pe-group; + } +} diff --git a/radio/fhi_72/mplane/yang/models/o-ran-uplane-conf.yang b/radio/fhi_72/mplane/yang/models/o-ran-uplane-conf.yang new file mode 100644 index 0000000000..16fbaf3335 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/o-ran-uplane-conf.yang @@ -0,0 +1,2706 @@ +module o-ran-uplane-conf { + yang-version 1.1; + namespace "urn:o-ran:uplane-conf:1.0"; + prefix "o-ran-uplane-conf"; + + import o-ran-processing-element { + prefix "o-ran-pe"; + } + + import ietf-interfaces { + prefix "if"; + } + + import o-ran-module-cap { + prefix "mcap"; + revision-date 2020-08-10; + } + + import o-ran-compression-factors { + prefix "cf"; + revision-date 2020-08-10; + } + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the module capabilities for + the O-RAN Radio Unit U-Plane configuration. + + Copyright 2020 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + + revision "2020-08-10" { + description + "version 4.0.0 + + 1) parameters allowing for static PRACH configuration introduced + 2) parameters allowing for static SRS configuration introduced + 3) parameters allowing for configuration of TDD pattern introduced + 4) Backward compatible change to introduce new parameter 'coupling-method' related + to Section Description Priority to serve for CUS-Plane CR"; + + reference "ORAN-WG4.M.0-v04.00"; + } + + revision "2020-04-17" { + description + "version 3.0.0 + + 1) Adding optional little endian support + 2) Adding a new capability parameter to indicate that the O-RU + supports regularizationFactor in section type 5 + 3) Added support for Dynamic Spectrum Sharing feature + 4) Clarify the supported number of reMasks in RU side + 5) Section extension for grouping multiple ports + 6) adding PRACH formats to endpoint capabilities"; + + reference "ORAN-WG4.M.0-v03.00"; + } + + revision "2019-07-03" { + description + "version 1.1.0 + + 1) added new leaf multiple-numerology-supported to enable O-RU to report + whether it supports multiple numerologies. + + 2) fixing broken constraints (configuration cannot be dependent on + operational state). This is a backwards incompatible revision. + + As these constraints only apply when the LAA feature is used, and also + when considering the limited number of implementation that need to be + taken into consideration for backwards compatibility, it has been + agreed to NOT increment the namespace integer. + + 3) added frequency related capabilities for tx-arrays and rx-array + + 4) removed redundant LAA import"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + feature EAXC-GAIN-CORRECTION { + description + "Presence of feature indicates that O-RU supports eAxC specific gain correction."; + } + + feature TX-REFERENCE-LEVEL { + description + "Presence of feature indicates that O-RU supports TX gain reference level control"; + } + + typedef prach-preamble-format { + type enumeration { + enum LTE-0 { + description + "LTE PRACH Preamble format 0"; + } + enum LTE-1 { + description + "LTE PRACH Preamble format 1"; + } + enum LTE-2 { + description + "LTE PRACH Preamble format 2"; + } + enum LTE-3 { + description + "LTE PRACH Preamble format 3"; + } + enum LTE-4 { + description + "LTE PRACH Preamble format 4"; + } + enum LTE-NB0 { + description + "LTE Narrowband PRACH format 0"; + } + enum LTE-NB1 { + description + "LTE Narrowband PRACH format 1"; + } + enum NR-0 { + description + "5GNR PRACH Preamble format 0"; + } + enum NR-1 { + description + "5GNR PRACH Preamble format 1"; + } + enum NR-2 { + description + "5GNR PRACH Preamble format 2"; + } + enum NR-3 { + description + "5GNR PRACH Preamble format 3"; + } + enum NR-A1 { + description + "5GNR PRACH Preamble format A1"; + } + enum NR-A2 { + description + "5GNR PRACH Preamble format A2"; + } + enum NR-A3 { + description + "5GNR PRACH Preamble format A3"; + } + enum NR-B1 { + description + "5GNR PRACH Preamble format B1"; + } + enum NR-B2 { + description + "5GNR PRACH Preamble format B2"; + } + enum NR-B3 { + description + "5GNR PRACH Preamble format B3"; + } + enum NR-B4 { + description + "5GNR PRACH Preamble format B4"; + } + enum NR-C0 { + description + "5GNR PRACH Preamble format C0"; + } + enum NR-C2 { + description + "5GNR PRACH Preamble format C2"; + } + } + + description + "PRACH preamble format definition"; + } + + typedef polarisation_type { + type enumeration { + enum MINUS_45 { + description "MINUS_45"; + } + enum ZERO { + description "ZERO"; + } + enum PLUS_45 { + description "PLUS_45"; + } + enum PLUS_90 { + description "PLUS_90"; + } + } + description "Type definition for polarisations"; + } + + grouping general-config { + description "a group for general configuration"; + + container general-config { + description "a container for general configuration"; + + leaf regularization-factor-se-configured { + type boolean; + default false; + description + "Informs if regularizationfactor in section extension is configured(true) or not(false), this + leaf indicates whether the O-DU will send the regularizationfactor in section extension. + + If the O-RU does not support regularization-factor-se-supported in o-ran-module-cap.yang, + this leaf is ignored."; + } + + leaf little-endian-byte-order { + type boolean; + default false; + + description + "If little endian byte order for C/U plane data flows is supported by + the O-RU, indicates if the O-RU should use little endian byte order + for all UL and DL C/U plane data flows. + + If little endian byte order is NOT supported, this node is ignored + (and the default bigendian byte order used)"; + } + } + } + + grouping laa-carrier-config { + description "Carrier Configuration for support of LAA. "; + leaf ed-threshold-pdsch { + type int8; + units dBm; + description + "This value indicates Energy Detection(ED) threshold for LBT for PDSCH and for measurements in dBm."; + } + + leaf ed-threshold-drs { + type int8; + units dBm; + description + "This value indicates Energy Detection(ED) threshold for LBT for DRS in dBm."; + } + + leaf tx-antenna-ports { + type uint8; + description + "This value indicates Tx antenna ports for DRS (1, 2, 4)"; + } + + leaf transmission-power-for-drs { + type int8; + units decibels; + description + "This value indicates offset of Cell specific reference Signal(CRS) power to reference signal power (dB). + DRS signal consists of CRS, PSS, SSS, and optionally CSI-RS."; + } + + leaf dmtc-period { + type enumeration { + enum FORTY { + description + "40 ms"; + } + enum EIGHTY { + description + "80 ms"; + } + enum ONE-HUNDRED-SIXTY { + description + "160 ms"; + } + } + units milliseconds; + description + "This value indicates DRS measurement timing configuration (DMTC) period in ms"; + } + + leaf dmtc-offset { + type uint8; + units subframes; + description + "This value indicates dmtc offset in Subframes."; + } + + leaf lbt-timer { + type uint16; + units milliseconds; + description + "This value indicates LBT Timer in milliseconds."; + } + + list max-cw-usage-counter { + when "/mcap:module-capability/mcap:rw-sub-band-info/mcap:rw-self-configure = 'true'"; + key "priority"; + description ""; + leaf priority { + type enumeration { + enum P1 { + description "priority 1"; + } + enum P2 { + description "priority 2"; + } + enum P3 { + description "priority 3"; + } + enum P4 { + description "priority 4"; + } + } + description "This value provides the priority class traffic for which the counter is calculated."; + } + + leaf counter-value { + type uint8 { + range "1..8"; + } + description "This value indicates the maximum value of counter + which shows how many max congestion window value is used for backoff + number of priority class traffic. This value is defined at 3GPP 36.213 + section 15.1.3 as K."; + } + } + } + + grouping coupling-methods { + description + "Grouping for configuration of desired C-Plane / U-Plane coupling methods (if supported)"; + leaf coupling-to { + type leafref { + path "/mcap:module-capability/mcap:ru-capabilities/mcap:coupling-methods/mcap:coupling-via-frequency-and-time"; + require-instance false; + } + + description + "RW instance of RO parameter."; + } + leaf coupling-method { + when "../coupling-to = 'true'"; + type enumeration{ + enum NORMAL { + description "Coupling via sectionId value. This value can be used always."; + } + enum FREQUENCY_AND_TIME { + description "Coupling via frequency and time. Can be used when coupling-via-frequency-and-time = true + or coupling-via-frequency-and-time-with-priorities = true in o-ran-module-cap.yang"; + } + enum FREQUENCY_AND_TIME_WITH_PRIORITIES { + description "Coupling via frequency and time with priorities. Can be used when + coupling-via-frequency-and-time-with-priorities = true in o-ran-module-cap.yang"; + } + } + default NORMAL; + description + "Method of coupling between C-Plane and U-Plane messages; see methods of coupling + of C-Plane and U-Plane in CUS-Plane specification"; + } + } + + grouping eaxc { + description + "One eAxC identifier (eAxC ID) comprises a band and sector + identifier (BandSector_ID), a component-carrier identifier (CC_ID) and a + spatial stream identifier (RU_Port_ID). + + In this version of the specification, one eAxC contains only one spatial + stream (i.e. one beam per subcarrier) at a time. + + Bit allocation is subdivided as follows: + * O_DU_Port_ID: Used to differentiate processing units at O-DU + * BandSector_ID: Aggregated cell identifier + * CC_ID: distinguishes Carrier Components + * RU_Port_ID: Used to differentiate spatial streams or beams on the O-RU + + The bitwidth of each of the above fields is variable this model is supposed to check + if we are occpying bits continuously but we do not have to occupy all 16 bits"; + + + leaf o-du-port-bitmask { + type uint16; + mandatory true; + description + "mask for eaxc-id bits used to encode O-DU Port ID"; + } + + leaf band-sector-bitmask { + type uint16; + mandatory true; + description + "mask for eaxc-id bits used to encode the band sector ID"; + } + + leaf ccid-bitmask { + type uint16; + mandatory true; + description + "mask for eaxc-id bits used to encode the component carrier id"; + } + + leaf ru-port-bitmask { + type uint16; + mandatory true; + description + "mask for eaxc-id bits used to encode the O-RU Port ID"; + } + + leaf eaxc-id { + type uint16; + mandatory true; + description + "encoded value of eaxcid to be read by CU-Plane"; + } + } + + grouping parameters { + description + "Grouping of all parameters common between UL and DL"; + + leaf name { + type string; + mandatory true; + description "Unique name of array antenna"; + } + + leaf number-of-rows { + type uint16; + mandatory true; + description "Number of rows array elements are shaped into - M"; + } + + leaf number-of-columns { + type uint16; + mandatory true; + description "Number of columns array elements are shaped into - N"; + } + + leaf number-of-array-layers { + type uint8; + mandatory true; + description "Number of array layers array elements are shaped into - Q"; + } + + leaf horizontal-spacing { + type decimal64 { + fraction-digits 5; + } + units Meter; + + description "Average distance between centers of nearby AE in horizontal direction (in array coordinates system)"; + } + + leaf vertical-spacing{ + type decimal64 { + fraction-digits 5; + } + units Meter; + + description "Average distance between centers of nearby AE in vertical direction (in array coordinates system)"; + } + + container normal-vector-direction { + description + "Counter-clockwise rotation around z and y axis."; + + leaf azimuth-angle{ + type decimal64 { + fraction-digits 4; + } + units Degrees; + + description "Azimuth angle, counter-clockwise rotation around z-axis. Value 'zero' points to broad-side, value '90' points to y-axis"; + } + leaf zenith-angle{ + type decimal64 { + fraction-digits 4; + } + units Degrees; + + description "Zenith angle, counter-clockwise rotation around y-axis. Value 'zero' points to zenith, value '90' points to horizon"; + } + } + + container leftmost-bottom-array-element-position { + description "Structure describing position of leftmost, bottom array element."; + leaf x { + type decimal64 { + fraction-digits 4; + } + units Meter; + + description "X dimension of position of leftmost, bottom array element"; + } + + leaf y { + type decimal64 { + fraction-digits 4; + } + units Meter; + + description "Y dimension of position of leftmost, bottom array element"; + } + + leaf z { + type decimal64 { + fraction-digits 4; + } + units Meter; + + description "Z dimension of position of leftmost, bottom array element"; + } + } + list polarisations { + key "p"; + min-elements 1; + max-elements 2; + + description + "List of supported polarisations."; + + leaf p { + type uint8; + mandatory true; + description + "Polarisation index. See CUS-plane"; + } + + leaf polarisation { + type polarisation_type; + mandatory true; + description "Type of polarisation supported by array."; + } + } + leaf band-number { + type leafref { + path "/mcap:module-capability/mcap:band-capabilities/mcap:band-number"; + } + mandatory true; + description + "This parameter informing which frequency band particular antenna + array is serving for. + Intended use is to deal with multiband solutions."; + } + } + + grouping array-choice { + choice antenna-type { + case tx { + leaf tx-array-name { + type leafref { + path "/o-ran-uplane-conf:user-plane-configuration/o-ran-uplane-conf:tx-arrays/o-ran-uplane-conf:name"; + } + + description + "Leafref to tx array if such is choosen"; + } + } + case rx { + leaf rx-array-name { + type leafref { + path "/o-ran-uplane-conf:user-plane-configuration/o-ran-uplane-conf:rx-arrays/o-ran-uplane-conf:name"; + } + + description + "Leafref to rx array if such is choosen"; + } + } + description + "Choice for antenna type"; + } + description + "Elements which groups choice for antenna type"; + } + + grouping scs-config { + description + "It groups all parameters related to SCS configuration"; + + leaf frame-structure { + type uint8; + + description + "This parameter defines the frame structure. The first 4 bits define the FFT/iFFT size + being used for all IQ data processing related to this message. + The second 4 bits define the sub carrier spacing as well as the number of slots per 1ms sub-frame + according to 3GPP TS 38.211, taking for completeness also 3GPP TS 36.211 into account"; + } + + leaf cp-type { + type enumeration { + enum NORMAL { + description + "Normal cyclic prefix"; + } + + enum EXTENDED { + description + "Extended cyclic prefix"; + } + } + + description + "Provides type of CP (cyclic prefix) if section type 3 is not used or type of CP cannot be determined from cpLength."; + } + + leaf cp-length { + type uint16; + units Ts; + mandatory true; + description + "Used for symbol 0 for NR & LTE, and symbol 7*2u for NR. + See CUS-plane"; + } + + leaf cp-length-other { + type uint16; + units Ts; + mandatory true; + description + "Used for other symbols than by cp-length above"; + } + + leaf offset-to-absolute-frequency-center { + type int32; + mandatory true; + description + "This provides value of freqOffset to be used if section type 3 is not used. See freqOffset in CUS-plane."; + } + + list number-of-prb-per-scs { + key scs; + description + "List of configured for each SCS that will be used."; + + leaf scs { + type mcap:scs-config-type; + description + "Value corresponds to SCS values defined for frameStructure in C-plane. + Note: set of allowed values is restricted by SCS derived from values in supported-frame-structures."; + } + + leaf number-of-prb { + type uint16; + mandatory true; + description + "Determines max number of PRBs that will be used in all sections per one symbol. + This is affecting allocation of resources to endpoint. Value shall not exceed constrains + defined by max-prb-per-symbol of endpoint type. In addition sum (over all used epoints + within a group of endpoints sharing resources) of number-of-prb rounded up to + nearest value from prb-capacity-allocation-granularity shall not exceed max-prb-per-symbol of the group."; + } + } + } + + grouping tx-common-array-carrier-elements { + description + "This grouping containes all common parameters for tx-array-carriers and rx-array-carriers"; + + leaf absolute-frequency-center { + type uint32; + mandatory true; + description + "Absolute Radio Frequency Channel Number - indirectly indicates RF center carrier frequency of signal. + Reflected in arfcn."; + } + + leaf center-of-channel-bandwidth { + type uint64; + units Hz; + mandatory true; + description + "Center frequency of channel bandwidth in Hz. Common for all numerologies."; + } + + leaf channel-bandwidth { + type uint64; + units Hz; + mandatory true; + + description + "Width of carrier given in Hertz"; + } + + leaf active { + type enumeration { + enum INACTIVE { + description + "carrier does not provide signal - transmission is disabled"; + } + enum SLEEP{ + description + "carrier is fully configured and was active but is energy saving mode"; + } + enum ACTIVE{ + description + "carrier is fully configured and properly providing the signal"; + } + } + default INACTIVE; + + description + "Indicates if transmission is enabled for this array carriers. Note that Netconf server uses state parameter + to indicate actual state of array carriers operation. When array carriers is in sleep status, + Netconf server rejects all other operation request to tx-array-carriers object except either request to change from sleep + to active status or delete MO operation (see 4.8) to the object."; + } + + leaf state { + type enumeration { + enum DISABLED { + description + "array carrier is not active - transmission of signal is disabled."; + } + enum BUSY { + description + "array carrier is processing an operation requested by change of active parameter. + When array carriers is BUSY the transmission of signal is not guaranteed."; + } + enum READY { + description + "array carrier had completed activation operation - is active and transmission of signal is ongoing."; + } + } + config false; + mandatory true; + description + "Indicates state of array carriers activation operation"; + } + + leaf type { + type enumeration { + enum NR { + description + "5G technology"; + } + enum LTE { + description + "LTE technology"; + } + enum DSS_LTE_NR { + if-feature mcap:DSS_LTE_NR; + description + "NR and LTE technologies in Dynamic Spectrum Sharing mode"; + } + } + description + "Type of carrier. Indicates array-carrier technology."; + } + + leaf duplex-scheme { + type enumeration { + enum TDD { + description + "TDD scheme"; + } + enum FDD { + description + "FDD scheme"; + } + } + config false; + + description + "Type of duplex scheme O-RU supports."; + } + leaf rw-duplex-scheme { + type leafref { + path "/user-plane-configuration/tx-array-carriers[name=current()/../name]" + "/duplex-scheme"; + require-instance false; + } + description + "Config true type of duplex scheme."; + } + leaf rw-type { + type leafref { + path "/user-plane-configuration/tx-array-carriers[name=current()/../name]" + "/type"; + require-instance false; + } + description + "Config true type of carrier."; + } + } + + grouping rx-common-array-carrier-elements { + description + "This grouping containes all common parameters for tx-array-carriers and rx-array-carriers"; + + leaf absolute-frequency-center { + type uint32; + mandatory true; + description + "Absolute Radio Frequency Channel Number - indirectly indicates RF center carrier frequency of signal. + Reflected in arfcn."; + } + + leaf center-of-channel-bandwidth { + type uint64; + units Hz; + mandatory true; + description + "Center frequency of channel bandwidth in Hz. Common for all numerologies."; + } + + leaf channel-bandwidth { + type uint64; + units Hz; + mandatory true; + + description + "Width of carrier given in Hertz"; + } + + leaf active { + type enumeration { + enum INACTIVE { + description + "carrier does not provide signal - transmission is disabled"; + } + enum SLEEP{ + description + "carrier is fully configured and was active but is energy saving mode"; + } + enum ACTIVE{ + description + "carrier is fully configured and properly providing the signal"; + } + } + default INACTIVE; + + description + "Indicates if transmission is enabled for this array carriers. Note that Netconf server uses state parameter + to indicate actual state of array carriers operation. When array carriers is in sleep status, + Netconf server rejects all other operation request to tx-array-carriers object except either request to change from sleep + to active status or delete MO operation (see 4.8) to the object."; + } + + leaf state { + type enumeration { + enum DISABLED { + description + "array carrier is not active - transmission of signal is disabled."; + } + enum BUSY { + description + "array carrier is processing an operation requested by change of active parameter. + When array carriers is BUSY the transmission of signal is not guaranteed."; + } + enum READY { + description + "array carrier had completed activation operation - is active and transmission of signal is ongoing."; + } + } + config false; + mandatory true; + description + "Indicates state of array carriers activation operation"; + } + + leaf type { + type enumeration { + enum NR { + description + "5G technology"; + } + enum LTE { + description + "LTE technology"; + } + enum DSS_LTE_NR { + if-feature mcap:DSS_LTE_NR; + description + "NR and LTE technologies in Dynamic Spectrum Sharing mode"; + } + } + description + "Type of carrier. Indicates array-carrier technology."; + } + + leaf duplex-scheme { + type enumeration { + enum TDD { + description + "TDD scheme"; + } + enum FDD { + description + "FDD scheme"; + } + } + config false; + + description + "Type of duplex scheme O-RU supports."; + } + } + + grouping endpoint-section-capacity { + leaf max-control-sections-per-data-section { + type uint8 { + range "1..12"; + } + description + "Max number of C-plane sections (C-plane section is part of C-plane message that carries 'section fields') + referring to same U-plane section (U-plane section is part of U-plane message that carries + 'section header fields' and 'PRB fields') that is supported by endpoint. + Note that additional limitations specific for each section type apply on top of this number."; + } + leaf max-sections-per-symbol { + type uint16; + description + "Max number of sections within one symbol that can be processed by endpoint + or processed collectively by group of endpoints sharing capacity"; + } + leaf max-sections-per-slot { + type uint16; + description + "Max number of sections within one slot that can be processed by endpoint + or processed collectively by group of endpoints sharing capacity."; + } + + leaf max-remasks-per-section-id { + type uint8 { + range "1..12"; + } + default 12; + description + "maximum number of different reMask values that is applied to a PRB + within one section id. This value can be processed by endpoint + or processed collectively by group of endpoints sharing capacity"; + } + + description + "Parameters describing section capacity where section is undestood as number of different sectionId values"; + } + + grouping endpoint-beam-capacity { + leaf max-beams-per-symbol { + type uint16; + description + "Max number of beams within one symbol that can be processed by endpoint + or processed collectively by group of endpoints sharing capacity"; + } + leaf max-beams-per-slot { + type uint16; + description + "Max number of beams within one slot that can be processed by endpoint + or processed collectively by group of endpoints sharing capacity"; + } + + description + "Parameters describing beam capacity where number of beams is understood as number of different beamId values"; + } + + grouping endpoint-prb-capacity { + leaf max-prb-per-symbol { + type uint16; + description + "Max number of prbs within one symbol that can be processed by endpoint + or processed collectively by group of endpoints sharing capacity"; + } + + description + "Attributes presenting processing capacity related to PRB."; + } + + grouping endpoint-numerology-capacity { + leaf max-numerologies-per-symbol { + type uint16; + description + "Max number of numerologies within one symbol that can be processed by endpoint + or processed collectively by group of endpoints sharing capacity"; + } + + description + "Attributes presenting processing capacity related to numerology. + + This leaf contains valid data only when multiple-numerology-supported + is set to true."; + } + + grouping endpoint-static-config-support { + leaf static-config-supported { + type enumeration { + enum NONE { + description + "The endpoint does not support static PRACH / SRS configuration. + Reception of PRACH / SRS is possible through real time C-Plane messages + if other endpoint capabilities allow for that."; + } + enum PRACH { + if-feature mcap:PRACH-STATIC-CONFIGURATION-SUPPORTED; + description + "The endpoint supports statically configured PRACH reception"; + } + enum SRS { + if-feature mcap:SRS-STATIC-CONFIGURATION-SUPPORTED; + description + "The endpoint supports statically configured SRS reception"; + } + } + default NONE; + + description + "The parameter informs if endpoint can be statically configured to process PRACH or SRS reception"; + } + + leaf max-prach-patterns { + when "(/user-plane-configuration/static-low-level-rx-endpoints[name=current()/../name]/static-config-supported = 'PRACH')"; + type uint8; + description + "Maximum number of PRACH patterns the endpoint can handle in PRACH configuration"; + } + + leaf max-srs-patterns { + when "(/user-plane-configuration/static-low-level-rx-endpoints[name=current()/../name]/static-config-supported = 'SRS')"; + type uint8; + description + "Maximum number of SRS patterns the endpoint can handle in SRS configuration"; + } + + description + "Endpoint's capabilities related to static PRACH / SRS configuration."; + } + + grouping endpoint-tdd-pattern-support { + leaf configurable-tdd-pattern-supported { + type boolean; + default false; + + description + "The parameter informs if endpoint supports configuration for TDD pattern"; + } + + leaf tdd-group { + type uint8; + description + "Parameter is used to group static-low-level-[tr]x-endpoints. + Note: [tr]x-array-carriers using static-low-level-[tr]x-endpoints + having the same value of tdd-group, must have the same TDD switching + points and the same directions to the air interface granted - regardless TDD switching + is controlled by M-Plane or by C-Plane"; + } + + description + "This grouping exposes static-low-level-[tr]x-endpoint's capabilities related to its support for configurable + TDD patterns and limitations regarding common TDD switching per groups of endpoints."; + } + + grouping uplane-conf-group { + description + "Grouping for uplane configuration related parameters"; + + list low-level-tx-links { + key name; + description + "Object model for low-level-tx-link configuration"; + + leaf name { + type string; + description + "Unique name of low-level-tx-link object."; + } + + leaf processing-element { + type leafref { + path "/o-ran-pe:processing-elements/o-ran-pe:ru-elements/o-ran-pe:name"; + } + mandatory true; + description + "Contains name of processing-element to be used as transport by low-level-tx-link"; + } + + leaf tx-array-carrier { + type leafref { + path "/user-plane-configuration/tx-array-carriers/name"; + } + mandatory true; + description + "Contains name of tx-array-carriers MO to be used as transport by low-level-tx-link"; + } + + leaf low-level-tx-endpoint { + type leafref { + path "/user-plane-configuration/low-level-tx-endpoints/name"; + } + mandatory true; + description + "Contains name of low-level-tx-endpoints MO to be used as transport by low-level-tx-link"; + } + } + + list low-level-rx-links { + key name; + description + "Object model for low-level-rx-links configuration"; + + leaf name { + type string; + + description + "Unique name of low-level-rx-links object."; + } + + leaf processing-element { + type leafref { + path "/o-ran-pe:processing-elements/o-ran-pe:ru-elements/o-ran-pe:name"; + } + mandatory true; + description + "Contains name of processing-element to be used as transport by LowLevelTxLink"; + } + + leaf rx-array-carrier { + type leafref { + path "/user-plane-configuration/rx-array-carriers/name"; + } + mandatory true; + + description + "Contains name of rx-array-carriers MO to be used as transport by low-level-rx-links"; + } + + leaf low-level-rx-endpoint { + type leafref { + path "/user-plane-configuration/low-level-rx-endpoints/name"; + } + mandatory true; + + description + "Contains name of low-level-rx-endpoints MO to be used as transport by low-level-rx-links"; + } + + leaf user-plane-uplink-marking { + type leafref { + path "/o-ran-pe:processing-elements/o-ran-pe:enhanced-uplane-mapping/o-ran-pe:uplane-mapping/o-ran-pe:up-marking-name"; + } + description + "Parameter to set the non-default marking for user-plane"; + } + } + + list endpoint-types { + key "id"; + config false; + description + "Properties of endpoint that are common to multiple endpoints if such are identified"; + + leaf id { + type uint16; + description + "Identifies type of endpoints sharing same properties. Values shall start with 0 and shall be allocated without gaps."; + } + + list supported-section-types { + key "section-type"; + description + "Indicates section types and extensions endpoints of this type support"; + + leaf section-type { + type uint8; + + description + "This parameter determines the characteristics of U-plane data to be transferred or received from a beam with one pattern id."; + } + + leaf-list supported-section-extensions { + type uint8; + + description + "This parameter provides the extension types supported by the O-RU + which provides additional parameters specific to the subject data extension"; + } + } + + leaf-list supported-frame-structures { + type uint8; + + description + "List of supported values of frame structure"; + } + + leaf managed-delay-support { + type enumeration { + enum MANAGED { + description + "Time managed delays are supported"; + } + + enum NON_MANAGED { + description + "Non time managed delays are supported"; + } + + enum BOTH { + description + "Both time managed and non time managed delays are supported"; + } + } + + description + "Type of delay supported by the endpoint"; + } + + leaf multiple-numerology-supported { + type boolean; + default true; + description + "Indicates whether the endpoint type supports multiple numerologies"; + } + + leaf max-numerology-change-duration { + type uint16 { + range "0..10000"; + } + + units Ts; + description + "Maximum gap of endpoint operation that will be caused by changing of + numerology. + + This time is required for reconfiguration and flushing of pipes. + + This leaf contains valid data only when multiple-numerology-supported + is set to true."; + } + + uses endpoint-section-capacity; + uses endpoint-beam-capacity; + uses endpoint-prb-capacity; + + leaf-list prb-capacity-allocation-granularity { + type uint16; + + description + "List of capacity allocation steps. O-RU allocates PRB capacity rounding it up to nearest value N + from prb-capacity-allocation-granularity such that M >= number-of-prb-per-scs. + See also number-of-prb-per-scs/number-of-prb."; + } + + uses endpoint-numerology-capacity; + } + + list endpoint-capacity-sharing-groups { + key "id"; + config false; + description + "Represents groups of endpoints that share capacity. Depending on O-RU implementation, + processing resources that handle CU-plane (e.g. memory to keep sections and beams) + could be allocated per endpoint or shared between several endpoints. + To address this O-RU shall reports own capability per endpoint (see endpoint-types) + and per group of endpoints sharing capacity. + If endpoint is in multiple groups then resulting constraint is minimum over all groups. + Note: values of parameters representing capacity that is not shared between endpoints in a group + shall be set to max value of specific parameter; this effectively removes related constraint."; + + leaf id { + type uint16; + description + "Identifies group of endpoints sharing resources. + Values shall start with 0 and shall be allocated without gaps."; + } + uses endpoint-section-capacity; + uses endpoint-beam-capacity; + uses endpoint-prb-capacity; + uses endpoint-numerology-capacity; + + leaf max-endpoints { + type uint16; + description + "Indicates how many endpoints in the group can be used4 simultaneously"; + } + leaf max-managed-delay-endpoints { + type uint16; + description + "Number of endpoints supporting managed delay that can be used (configured for use) at a time"; + } + leaf max-non-managed-delay-endpoints { + type uint16; + description + "Number of endpoints supporting non-managed delay that can be used (configured for use) at a time"; + } + } + + list endpoint-prach-group { + key "id"; + config false; + description + "Represents group of a series of PRACH preamble formats"; + + leaf id { + type uint16; + description + "Identifies group of PRACH preamble formats."; + } + + leaf-list supported-prach-preamble-formats { + type prach-preamble-format; + min-elements 1; + description + "the list of PRACH preamble formats supported by the endpoint-type that is + applicable to static-low-level-rx-endpoints in the O-RU"; + } + + } + + list supported-compression-method-sets { + key "id"; + config false; + description + "List of available compression methods supported by device"; + + leaf id { + type uint16; + description + "Identification number for compression method set"; + } + + list compression-method-supported { + uses cf:compression-parameters; + + leaf-list fs-offset { + if-feature cf:CONFIGURABLE-FS-OFFSET; + type uint8; + default 0; + description + "Adjusts FS (full scale) value of IQ format relative to FS derived from unmodified IQ format. + Please refer to CU-Plane specification for details"; + + } + description + "List of supported compression methods by O-RU + Note: if O-RU supports different compression methods per endpoint + then please refer to endpoints to have information what + exactly is supported on paticular endpoint"; + } + } + + list static-low-level-tx-endpoints { + key name; + config false; + description + "Object model for static-low-level-tx-endpoints configuration"; + + leaf name { + type string; + + description + "Unique name of static-low-level-tx-endpoints object."; + } + + leaf-list restricted-interfaces { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + description + "Optionally used to indicate that a low-level link is constrained to operate only via a subset of the available interfaces."; + } + + leaf array { + type leafref { + path "/user-plane-configuration/tx-arrays/name"; + } + mandatory true; + description + "Contains distname of tx-arrays, particular low-level-tx-endpoints is in hardware dependency with. + Note: single instance of tx-arrays can be referenced by many instances of low-level-tx-endpoints + (e.g. to allow DU to handle multiple fronthauls and multiple component carriers)."; + } + + leaf endpoint-type { + type leafref { + path "../../endpoint-types/id"; + } + + description + "Reference to endpoint type capabilities list element supported by this endpoint"; + } + + leaf-list capacity-sharing-groups { + type leafref { + path "../../endpoint-capacity-sharing-groups/id"; + } + + description + "Reference to capacities of sharing-groups supported by this endpoint"; + } + + list supported-reference-level { + if-feature TX-REFERENCE-LEVEL; + key "id"; + description + "Informs about supported ranges for gain reference level."; + + leaf id { + type uint16; + description + "Identification number for particular range"; + } + + leaf min { + type decimal64 { + fraction-digits 4; + } + units dB; + mandatory true; + description + "Minimum of supported gain reference level"; + } + + leaf max { + type decimal64 { + fraction-digits 4; + } + units dB; + mandatory true; + description + "Maximum of supported gain reference level"; + } + } + + container compression { + description + "Container collecting compression related parameters."; + + leaf dynamic-compression-supported { + type boolean; + + description + "Informs if endpoint supports dynamic compression method"; + } + + leaf realtime-variable-bit-width-supported { + type boolean; + + description + "Informs if endpoint supports realtime variable bit with"; + } + + leaf supported-compression-set-id { + type leafref { + path "../../../supported-compression-method-sets/id"; + } + + description + "Id of supported compression set for this endpoint"; + } + } + + uses endpoint-tdd-pattern-support; + + } + + list static-low-level-rx-endpoints { + key name; + config false; + description + "Object model for static-low-level-rx-endpoints configuration"; + + leaf name { + type string; + + description + "Unique name of static-low-level-rx-endpoints object."; + } + + leaf-list restricted-interfaces { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + description + "Optionally used to indicate that a low-level link is constrained to operate only via a subset of the available interfaces."; + } + + leaf array { + type leafref { + path "/user-plane-configuration/rx-arrays/name"; + } + mandatory true; + description + "Contains distname of rx-arrays, particular low-level-rx-endpoints is in hardware dependency with. + Note: single instance of rx-arrays can be referenced by many instances of low-level-rx-endpoints + (e.g. to allow DU to handle multiple fronthauls and multiple component carriers)."; + } + + leaf endpoint-type { + type leafref { + path "../../endpoint-types/id"; + } + + description + "Reference to endpoint type capabilities list element supported by this endpoint"; + } + + leaf-list capacity-sharing-groups { + type leafref { + path "../../endpoint-capacity-sharing-groups/id"; + } + + description + "Reference to capacities of sharing-groups supported by this endpoint"; + } + + leaf prach-group { + type leafref { + path "../../endpoint-prach-group/id"; + require-instance false; + } + description + "An optional leaf used for those rx endpoints that support PRACH, indicating + the group id describing the set of of PRACH preambles supported"; + } + + container compression { + description + "Container collecting compression related parameters."; + + leaf dynamic-compression-supported { + type boolean; + + description + "Informs if endpoint supports dynamic compression method"; + } + + leaf realtime-variable-bit-width-supported { + type boolean; + + description + "Informs if endpoint supports realtime variable bit with"; + } + + leaf supported-compression-set-id { + type leafref { + path "../../../supported-compression-method-sets/id"; + } + + description + "Id of supported compression set for this endpoint"; + } + } + + uses endpoint-static-config-support; + + uses endpoint-tdd-pattern-support; + + } + + list low-level-tx-endpoints { + key "name"; + + description + "Object model for low-level-tx-endpoints configuration - augmented static-low-level-tx-endpoints by local-address + which cannot be added to static low-level-tx-endpoints as we cannot have modificable element in static object"; + + leaf name { + type leafref { + path "/user-plane-configuration/static-low-level-tx-endpoints/name"; + require-instance false; + } + mandatory true; + + description + "Unique name of low-level-tx-endpoint object. Reference to static object"; + } + + container compression { + presence + "This container shall exists to avoid missaligned compression + methods between devices"; + + description + "Container which consists of global configurable parameters for compression"; + + uses cf:compression-details; + + leaf fs-offset { + if-feature cf:CONFIGURABLE-FS-OFFSET; + type uint8; + default 0; + description + "Adjusts FS (full scale) value of IQ format relative to FS derived from unmodified IQ format. + Please refer to CU-Plane specification for details"; + } + + list dynamic-compression-configuration { + when "../compression-type = 'DYNAMIC'"; + key "id"; + unique "compression-method iq-bitwidth fs-offset"; + description + "List of possible configuration in case dynamic configuration is used + Note: In case of empty list all available compressions can be choosen dynamically + and default fs-offset is taken (0)."; + + leaf id { + type uint16; + description + "Identification number for particular compression"; + } + + uses cf:compression-method-grouping; + + leaf fs-offset { + if-feature cf:CONFIGURABLE-FS-OFFSET; + type uint8; + default 0; + description + "Adjusts FS (full scale) value of IQ format relative to FS derived from unmodified IQ format. + Please refer to CU-Plane specification for details"; + } + } + } + + uses scs-config; + + container e-axcid { + uses eaxc; + + description + "Contains local address of low level TX endpoint offered by Netconf server."; + } + + uses coupling-methods; + + leaf configurable-tdd-pattern-supported { + type leafref { + path "/user-plane-configuration/static-low-level-rx-endpoints[name=current()/../name]/configurable-tdd-pattern-supported"; + require-instance false; + } + description "RO to RW parameter mapping - needed for conditional under tx-array-carrier"; + } + } + + list low-level-rx-endpoints { + key name; + + description + "Object model for low-level-rx-endpoint configuration - augmented static-low-level-rx-endpoints by local-address + which cannot be added to static low-level-rx-endpoints as we cannot have modificable element in static object"; + + leaf name { + type leafref { + path "/user-plane-configuration/static-low-level-rx-endpoints/name"; + require-instance false; + } + mandatory true; + + description + "Unique name of low-level-rx-endpoint object. Reference to static object"; + } + + container compression { + description + "Container which consists of global configurable parameters for compression"; + + uses cf:compression-details; + + leaf fs-offset { + if-feature cf:CONFIGURABLE-FS-OFFSET; + type uint8; + default 0; + description + "Adjusts FS (full scale) value of IQ format relative to FS derived from unmodified IQ format. + Please refer to CU-Plane specification for details"; + } + + list dynamic-compression-configuration { + when "../compression-type = 'DYNAMIC'"; + key "id"; + unique "compression-method iq-bitwidth fs-offset"; + description + "List of possible configuration in case dynamic configuration is used + Note: In case of empty list all available compressions can be choosen dynamically + and default fs-offset is taken (0)."; + + leaf id { + type uint16; + description + "Identification number for particular compression"; + } + + uses cf:compression-method-grouping; + + leaf fs-offset { + if-feature cf:CONFIGURABLE-FS-OFFSET; + type uint8; + default 0; + description + "Adjusts FS (full scale) value of IQ format relative to FS derived from unmodified IQ format. + Please refer to CU-Plane specification for details"; + } + } + } + + uses scs-config; + + list ul-fft-sampling-offsets { + key scs; + description + "List of FFT sampling offsets configured for each SCS that will be used. + Client shall configure one element for each SCS that will be used."; + + leaf scs { + type mcap:scs-config-type; + description + "Value corresponds to SCS values defined for frameStructure in C-plane + Note: set of allowed values is restricted by SCS derived from values in supported-frame-structures."; + } + + leaf ul-fft-sampling-offset { + type uint16; + + units Ts; + description + "Determines time advance of capture window for FFT. + Value represents time advance of capture window start in relation to the end of CP. Unit is Ts. + Note: value of this parameter is usually set to '0' (zero) for PRACH channels. + Any phase offset resulting from the non-zero value of this parameter is handled in O-DU."; + } + } + + container e-axcid { + uses eaxc; + + description + "Contains local address of low level RX endpoint offered by Netconf server."; + } + + leaf eaxc-gain-correction { + if-feature EAXC-GAIN-CORRECTION; + type decimal64 { + fraction-digits 4; + } + units dB; + default 0; + description + "eAxC specifc part of overall gain_correction. + gain_correction = common array-carrier gain-correction + eAxC-gain-correction."; + } + + leaf non-time-managed-delay-enabled { + type boolean; + default false; + description + "Tells if non time managed delay shall be enabled"; + } + + uses coupling-methods; + + leaf static-config-supported { + type leafref { + path "/user-plane-configuration/static-low-level-rx-endpoints[name=current()/../name]/static-config-supported"; + require-instance false; + } + description "RO to RW parameter mapping - for further conditionals"; + } + + leaf static-prach-configuration { + when "(/user-plane-configuration/low-level-rx-endpoints[name=current()/../name]/static-config-supported = 'PRACH')"; + if-feature mcap:PRACH-STATIC-CONFIGURATION-SUPPORTED; + type leafref { + path "/user-plane-configuration/static-prach-configurations/static-prach-config-id"; + } + description + "This parameter creates reference to static PRACH configuration applicable for particular endpoint"; + } + + leaf static-srs-configuration { + when "(/user-plane-configuration/low-level-rx-endpoints[name=current()/../name]/static-config-supported = 'SRS')"; + if-feature mcap:SRS-STATIC-CONFIGURATION-SUPPORTED; + type leafref { + path "/user-plane-configuration/static-srs-configurations/static-srs-config-id"; + } + description + "This parameter creates reference to static SRS configuration applicable for particular endpoint"; + } + + leaf configurable-tdd-pattern-supported { + if-feature mcap:CONFIGURABLE-TDD-PATTERN-SUPPORTED; + type leafref { + path "/user-plane-configuration/static-low-level-rx-endpoints[name=current()/../name]/configurable-tdd-pattern-supported"; + require-instance false; + } + description "RO to RW parameter mapping - needed for conditional under rx-array-carrier"; + } + } + + list tx-array-carriers { + key name; + description + "Object model for tx-array-carriers configuration"; + + leaf name { + type string; + + description + "Unique name of tx-array-carriers object."; + } + + uses tx-common-array-carrier-elements; + + leaf band-number { + if-feature mcap:LAA; + type leafref { + path "/mcap:module-capability/mcap:band-capabilities/mcap:band-number"; + require-instance false; + } + description + "This parameter informing which frequency band particular antenna + array is serving for. + Intended use is to deal with multiband solutions."; + } + + container lte-tdd-frame { + when "(/user-plane-configuration/tx-array-carriers/rw-type = 'LTE') and (/user-plane-configuration/tx-array-carriers/rw-duplex-scheme = 'TDD')"; + status deprecated; + description + "Container which consists of global configurable parameters for tdd Frame. + This contained is deprecated due to introduction of TDD pattern configuration + applicable in a common way for LTE and NR."; + + leaf subframe-assignment { + type enumeration { + enum SAO { + description "subframe assignment configuration 0"; + } + enum SA1 { + description "subframe assignment configuration 1"; + } + enum SA2 { + description "subframe assignment configuration 2"; + } + enum SA3 { + description "subframe assignment configuration 3"; + } + enum SA4 { + description "subframe assignment configuration 4"; + } + enum SA5 { + description "subframe assignment configuration 5"; + } + enum SA6 { + description "subframe assignment configuration 6"; + } + } + mandatory true; + description + "Indicates DL/UL subframe configuration as specified in + 3GPP TS 36.211 [v15.3.0, table 4.2-2]"; + } + leaf special-subframe-pattern { + type enumeration { + enum SPP0 { + description "special subframe pattern configuration 0"; + } + enum SPP1 { + description "special subframe pattern configuration 1"; + } + enum SPP2 { + description "special subframe pattern configuration 2"; + } + enum SPP3 { + description "special subframe pattern configuration 3"; + } + enum SPP4 { + description "special subframe pattern configuration 4"; + } + enum SPP5 { + description "special subframe pattern configuration 5"; + } + enum SPP6 { + description "special subframe pattern configuration 6"; + } + enum SPP7 { + description "special subframe pattern configuration 7"; + } + enum SPP8 { + description "special subframe pattern configuration 8"; + } + enum SPP9 { + description "special subframe pattern configuration 9"; + } + enum SPP10 { + description "special subframe pattern configuration 10"; + } + } + mandatory true; + description + "Indicates TDD special subframe configuration as in TS 36.211 + [v15.3.0, table 4.2-1] "; + } + } + + container laa-carrier-configuration { + when "../band-number = 46"; + if-feature mcap:LAA; + description "Container to specify LAA feature related carrier configuration."; + uses laa-carrier-config; + } + + leaf gain { + type decimal64 { + fraction-digits 4; + } + units dB; + mandatory true; + + description + "Transmission gain in dB. Value applicable to each array element carrier belonging to array carrier."; + } + + leaf downlink-radio-frame-offset { + type uint32 { + range 0..12288000; + } + mandatory true; + + description + "This parameter is used for offsetting the starting position of 10ms radio frame. + Note: The value should have same value within DU to all tx-array-carrierss that have same frequency and bandwidth. + Note2: Unit is 1/1.2288e9 Hz and accuracy is 1/4 Tc. Then, its range is calculated 0..12288000."; + } + + leaf downlink-sfn-offset { + type int16 { + range -32768..32767; + } + mandatory true; + + description + "This parameter is used for offsetting SFN value. + Unit is in 10ms. + Note: The value should have same value within DU to all tx-array-carrierss that have same frequency and bandwidth."; + } + + leaf reference-level { + if-feature TX-REFERENCE-LEVEL; + type decimal64 { + fraction-digits 4; + } + units dB; + default 0; + description + "Allows to adjust reference level for sum of IQ signal power over eAxCs in this array-carrier."; + } + + leaf configurable-tdd-pattern { + when "not(/user-plane-configuration/low-level-tx-endpoints[name = string(/user-plane-configuration/low-level-tx-links[tx-array-carrier = current()/../name]/tx-array-carrier)]/configurable-tdd-pattern-supported = 'false')"; + if-feature mcap:CONFIGURABLE-TDD-PATTERN-SUPPORTED; + type leafref { + path "/user-plane-configuration/configurable-tdd-patterns/tdd-pattern-id"; + } + description + "This parameter creates reference to configuration for TDD pattern applicable for particular tx-array-carrier. + The leaf may exist under tx-array-carrier only in case O-RU supports feature 'CONFIGURABLE-TDD-PATTERN-SUPPORTED' + AND all low-level-tx-endpoints linked to this tx-array-carrier have configurable-tdd-pattern-supported = 'true'"; + } + } + + list rx-array-carriers { + key name; + description + "Object model for rx-array-carriers configuration"; + + leaf name { + type string; + description + "Unique name of rx-array-carriers object."; + } + + uses rx-common-array-carrier-elements; + + leaf downlink-radio-frame-offset { + type uint32 { + range 0..12288000; + } + mandatory true; + + description + "This parameter is used for offsetting the starting position of 10ms radio frame. + Note: The value should have same value within DU to all tx-array-carrierss that have same frequency and bandwidth. + Note2: Unit is 1/1.2288e9 Hz and accuracy is 1/4 Tc. Then, its range is calculated 0..12288000."; + } + + leaf downlink-sfn-offset { + type int16 { + range -32768..32767; + } + mandatory true; + + description + "This parameter is used for offsetting SFN value. + Unit is in 10ms. + Note: The value should have same value within DU to all tx-array-carrierss that have same frequency and bandwidth."; + } + + leaf gain-correction { + type decimal64 { + fraction-digits 4; + + } + units dB; + mandatory true; + description + "Gain correction of RF path linked with array element or array layers. + Common part of overall gain_correction. + gain_correction = common array-carrier gain-correction + eAxC gain correction."; + } + + leaf n-ta-offset { + type uint32; + units Tc; + mandatory true; + description + "Value of configurable N-TA offset + units are Tc=~0.5ns=1/1.96608GHz"; + } + + leaf configurable-tdd-pattern { + when "not(/user-plane-configuration/low-level-rx-endpoints[name = string(/user-plane-configuration/low-level-rx-links[rx-array-carrier = current()/../name]/rx-array-carrier)]/configurable-tdd-pattern-supported = 'false')"; + if-feature mcap:CONFIGURABLE-TDD-PATTERN-SUPPORTED; + type leafref { + path "/user-plane-configuration/configurable-tdd-patterns/tdd-pattern-id"; + } + description + "This parameter creates reference to configuration for TDD pattern applicable for particular rx-array-carrier. + The leaf may exist under rx-array-carrier only in case O-RU supports feature 'CONFIGURABLE-TDD-PATTERN-SUPPORTED' + AND all low-level-rx-endpoints linked to this rx-array-carrier have configurable-tdd-pattern-supported = 'true'"; + } + } + + list tx-arrays { + key "name"; + config false; + description + "Structure describing TX array parameters"; + + uses parameters; + + leaf max-gain { + type decimal64 { + fraction-digits 4; + + } + units dB; + mandatory true; + description + "Max gain of RF path linked with array element (minimum over elements of array) or array layers"; + } + + leaf independent-power-budget { + type boolean; + mandatory true; + description + "If true then every element of array has own, power budget independent from power budget of other elements. + Else all elements of array that are at same row and column and have same polarization share power budget"; + } + + list capabilities { + description + "List of capabilities related to this tx-array"; + uses mcap:support-for-dl; + } + } + + list rx-arrays { + key "name"; + config false; + description "Structure describing RX array parameters"; + + uses parameters; + container gain-correction-range { + leaf max { + type decimal64 { + fraction-digits 4; + } + units dB; + mandatory true; + description "Array gain correction factor - maximum allowed value"; + } + leaf min { + type decimal64 { + fraction-digits 4; + } + units dB; + mandatory true; + description "Array gain correction factor - minimum allowed value"; + } + + description + "Array gain correction factor"; + } + + list capabilities { + description + "List of capabilities related to this rx-array"; + uses mcap:support-for-ul; + } + } + + list relations { + key "entity"; + config false; + description "Structure describing relations between array elements"; + + leaf entity { + type uint16; + + description + "Relation entity. Used as a key for list of relations."; + } + + container array1 { + uses array-choice; + + description + "Defnes name for first array"; + } + container array2 { + uses array-choice; + + description + "Defnes name for second array"; + } + list types { + key "relation-type"; + description + "Defines relation type and pairs for array elements for given arrays"; + + leaf relation-type { + type enumeration { + enum SHARED { + description "SHARED"; + } + enum COALOCATED { + description "COALOCATED"; + } + } + description "Type of relation between array elements"; + } + list pairs { + key "element-array1"; + description + "defines related array elements"; + + leaf element-array1 { + type uint16; + + description + "Tells about id of element from array1"; + } + leaf element-array2 { + type uint16; + + description + "Tells about id of element from array2"; + } + } + } + } + + container eaxc-id-group-configuration { + if-feature mcap:EAXC-ID-GROUP-SUPPORTED; + description + "This is the container for eAxC ID group configuration."; + leaf max-num-tx-eaxc-id-groups { + type leafref { + path "/mcap:module-capability/mcap:ru-capabilities/mcap:eaxcid-grouping-capabilities/mcap:max-num-tx-eaxc-id-groups"; + require-instance false; + } + description "eaxc-id-group-configuration"; + } + leaf max-num-tx-eaxc-ids-per-group { + type leafref { + path "/mcap:module-capability/mcap:ru-capabilities/mcap:eaxcid-grouping-capabilities/mcap:max-num-tx-eaxc-ids-per-group"; + require-instance false; + } + description "max-num-tx-eaxc-ids-per-group"; + } + leaf max-num-rx-eaxc-id-groups { + type leafref { + path "/mcap:module-capability/mcap:ru-capabilities/mcap:eaxcid-grouping-capabilities/mcap:max-num-rx-eaxc-id-groups"; + require-instance false; + } + description "max-num-rx-eaxc-id-groups"; + } + leaf max-num-rx-eaxc-ids-per-group { + type leafref { + path "/mcap:module-capability/mcap:ru-capabilities/mcap:eaxcid-grouping-capabilities/mcap:max-num-rx-eaxc-ids-per-group"; + require-instance false; + } + description "max-num-rx-eaxc-ids-per-group"; + } + + list tx-eaxc-id-group { + must "count(../tx-eaxc-id-group) <= ../max-num-tx-eaxc-id-groups" { + error-message "too many tx-eaxcid-id groups"; + } + key "representative-tx-eaxc-id"; + description + "This is a list of the groups of the eAxC IDs assigned to low-level-tx-endpoints. + Each group is a union of the 'member-tx-eaxc-id's and a 'representative-tx-eaxc-id'. + The low-level-tx-endpoint associated to 'representative-tx-eaxc-id' is able to + process the DL C-plane information for all the low-level-tx-endpoints associated + to 'member-tx-eaxc-id's. + + Take Note: This list should only contain eAxC IDs assigned to a tx-endpoint."; + + + leaf representative-tx-eaxc-id { + type uint16; + description + "This parameter contains eAxC_ID that populates content of C-Plane section + extension 11 to eAxC_IDs configured in the group as 'member-tx-eaxc-id'(s)."; + } + leaf-list member-tx-eaxc-id { + type uint16; + must "count(../member-tx-eaxc-id) <= ../../max-num-tx-eaxc-ids-per-group" { + error-message "too many tx-eaxcid-id members"; + } + must "current()!=../representative-tx-eaxc-id" { + error-message "the representative eaxcid does not need to be a list member"; + } + description + "This is a list of member eAxC IDs, which together with the representative-tx-eaxc-id, + are assigned to low-level-tx-endpoints in the group."; + } + } + + list rx-eaxc-id-group { + must "count(../rx-eaxc-id-group) <= ../max-num-rx-eaxc-id-groups" { + error-message "too many rx-eaxcid-id groups"; + } + key "representative-rx-eaxc-id"; + description + "This is a list of the groups of the eAxC IDs assigned to low-level-rx-endpoints. + Each group is a union of 'member-rx-eaxc-id's and a 'representative-rx-eaxc-id'. + The low-level-rx-endpoint associated to 'representative-rx-eaxc-id' is able to + process the UL C-plane information for all the low-level-rx-endpoints associated + to 'member-rx-eaxc-id's. + + Take Note: This list should only contain eAxC IDs assigned to a rx-endpoint."; + + leaf representative-rx-eaxc-id { + type uint16; + description + "This parameter contains eAxC_ID that populates content of C-Plane section + extension 11 to eAxC_IDs configured in the group as 'member-rx-eaxc-id'(s)."; + } + + leaf-list member-rx-eaxc-id { + type uint16; + must "count(../member-rx-eaxc-id) <= ../../max-num-rx-eaxc-ids-per-group" { + error-message "too many rx-eaxcid-id members"; + } + must "current()!=../representative-rx-eaxc-id" { + error-message "the representative eaxcid does not need to be a list member"; + } + description + "This is a list of member eAxC IDs assigned to low-level-rx-endpoints in the group."; + } + } + } + + list static-prach-configurations { + if-feature mcap:PRACH-STATIC-CONFIGURATION-SUPPORTED; + key static-prach-config-id; + description + "List of static PRACH configurations. An O-RU shall reject any configuration + modification which exceed the maximum permitted configurations supported by + the O-RU"; + + leaf static-prach-config-id { + type uint8; + description + "Supplementary parameter acting as key in list of static PRACH configurations."; + } + + uses static-prach-configuration; + } + + grouping static-prach-configuration { + description + "Set of parameters related to static PRACH configuration"; + + leaf pattern-period { + type uint16 { + range 1..1024; + } + mandatory true; + description + "Period after which static PRACH patterns are repeated. Unit: number of frames."; + } + + leaf guard-tone-low-re { + type uint32; + mandatory true; + description + "Number of REs occupied by the low guard tones."; + } + + leaf num-prach-re { + type uint32; + mandatory true; + description + "Number of contiguous PRBs per data section description"; + } + + leaf guard-tone-high-re { + type uint32; + mandatory true; + description + "Number of REs occupied by the high guard tones."; + } + + leaf sequence-duration { + type uint32 { + range 256..24576; + } + units Ts; + mandatory true; + description + "Duration of single sequence of the PRACH. Sequence may be considered as 'single PRACH symbol'"; + } + + list prach-patterns { + key prach-pattern-id; + min-elements 1; + description + "Provides a PRACH pattern. Each record in the list represents a single PRACH occasion. Number of list entries cannot exceed max-prach-patterns"; + + leaf prach-pattern-id { + type uint16; + mandatory true; + description + "Supplementary parameter acting as key for prach-pattern list."; + } + + leaf number-of-repetitions { + type uint8{ + range 1..14; + } + mandatory true; + description + "This parameter defines number of PRACH repetitions in PRACH occasion, + to which the section control is applicable."; + } + + leaf number-of-occasions { + type uint8; + mandatory true; + description + "This parameter informs how many consecutive PRACH occasions is described by the PRACH pattern."; + } + + leaf re-offset { + type uint32; + mandatory true; + description + "Offset between the start of lowest-frequency RE of lowest-frequency PRB + and the start of lowest-frequency RE belonging to the PRACH occasion. + The re-offset is configured as number of PRACH REs."; + } + + list occasion-parameters { + key occasion-id; + min-elements 1; + description + "This is list of cp-lengths, gp-lengths and beam-ids applicable + per each PRACH occasion in PRACH pattern. + Note: the number of records in this list MUST be equal + to value of parameter number-of-occasions."; + + leaf occasion-id { + type uint8; + mandatory true; + description + "Supplementary parameter acting as key in 'occasion-parameters' list"; + } + + leaf cp-length { + type uint16; + units Ts; + mandatory true; + description + "Cyclic prefix length. See CUS-plane specification for detailed description."; + } + + leaf gp-length { + type uint16; + units Ts; + description + "Guard period length."; + } + + leaf beam-id { + type uint16; + mandatory true; + description + "This parameter defines the beam pattern to be applied to the U-Plane data. + beamId = 0 means no beamforming operation will be performed."; + } + } + + leaf frame-number { + type uint16{ + range 0..1023; + } + mandatory true; + description + "This parameter is an index inside the pattern-length, such that + PRACH occasion is happening for SFN which fulfills following equation: + [SFN mod pattern-length = frame-id]"; + } + + leaf sub-frame-id { + type uint16; + mandatory true; + description + "Identifier of sub-frame of the PRACH occasion. Value is interpreted in the same way + as subframeId field in a section description of a C-Plane message."; + } + + leaf time-offset { + type uint16; + units Ts; + mandatory true; + description + "This parameter defines the time-offset from the start of the sub-frame + to the start of the first Cyclic Prefix of PRACH pattern"; + } + } + } + + grouping static-srs-configuration { + description + "Set of parameters related to static PRACH configuration"; + + leaf pattern-period { + type uint16 { + range 1..1024; + } + mandatory true; + description + "Period after which static SRS patterns are repeated. Unit: number of frames."; + } + + list srs-patterns { + key srs-pattern-id; + min-elements 1; + description + "Provides a SRS pattern. Each record in the list represents a single PRACH occasion. Number of list entries cannot exceed max-srs-patterns."; + + leaf srs-pattern-id { + type uint16; + mandatory true; + description + "Supplementary parameter acting as key for srs-pattern list."; + } + + leaf sub-frame-id { + type uint16; + mandatory true; + description + "Identifier of sub-frame of the Raw SRS occasion. Value is interpreted in the same way + as subframeId field in a section description of a C-Plane message."; + } + + leaf slot-id { + type uint16; + mandatory true; + description + "Identifier of slot of the Raw SRS occasion. Value is interpreted in the same way + as slotId field in a section description of a C-Plane message."; + } + + leaf start-symbol-id { + type uint16; + mandatory true; + description + "Identifier of first symbol of the Raw SRS occasion. Value is interpreted in the same way + as startSymbolId field in a section description of a C-Plane message."; + } + + leaf beam-id { + type uint16; + mandatory true; + description + "This parameter defines the beam pattern to be applied to the U-Plane data. + beamId = 0 means no beamforming operation will be performed."; + } + + leaf num-symbol { + type uint16; + mandatory true; + description + "This parameter defines number of consecutive symbols covered by specific srs-pattern. + Single srs-pattern may address at least one symbol. However, possible optimizations + could allow for several (up to 14) symbols."; + } + + leaf start-prbc { + type uint16 { + range 0..1023; + } + mandatory true; + description + "Identifier of first PRB of the Raw SRS occasion. Value is interpreted in the same way + as startPrbc field in a section description of a C-Plane message."; + } + + leaf num-prbc { + type uint16; + mandatory true; + description + "Number of PRBs of the Raw SRS occasion. Value is interpreted in the same way + as numPrbc field in a section description of a C-Plane message."; + } + } + } + + grouping configurable-tdd-pattern { + description + "Set of parameters related to configurable TDD pattern. + Note: configurable-tdd-pattern shall not be used in case the usage would collide with + deprecated 'lte-tdd-pattern'."; + + list switching-points { + key switching-point-id; + description + "List of switching points within frame, related to configurable TDD pattern. + An O-RU shall reject any configuration modification which exceeds the maximum + number of switching-points supported by the O-RU"; + + leaf switching-point-id { + type uint16; + description + "Supplementary parameter acting as key for switching-points list."; + } + + leaf direction { + type enumeration { + enum UL { + description "Uplink"; + } + enum DL { + description "Downlink"; + } + enum GP { + description "Guard period"; + } + } + mandatory true; + description + "Parameter provides information regarding desired signal direction at the moment switching point occurs."; + } + + leaf frame-offset { + type uint32; + mandatory true; + description + "Offset from DL air frame boundary transmitted at RF connector to the point in time that is characteristic to the operation on RF switches. Unit is 1/1.2288e9 Hz and accuracy is 1/4 Tc."; + } + } + } + + list static-srs-configurations { + if-feature mcap:SRS-STATIC-CONFIGURATION-SUPPORTED; + key static-srs-config-id; + description + "List of static SRS configurations"; + + leaf static-srs-config-id { + type uint8; + description + "Supplementary parameter acting as key in the list of static SRS configurations."; + } + + uses static-srs-configuration; + } + + list configurable-tdd-patterns { + if-feature mcap:CONFIGURABLE-TDD-PATTERN-SUPPORTED; + key tdd-pattern-id; + description + "List of configured TDD patterns"; + + leaf tdd-pattern-id { + type uint8; + description + "Supplementary parameter acting as key in the list of configured TDD patterns."; + } + + uses configurable-tdd-pattern; + } + } + + grouping tx-array-notification-group { + description + "Grouping for tx-array for notification"; + + list tx-array-carriers{ + key name; + description "notification of state change for tx-array-carriers"; + + leaf name{ + type leafref{ + path "/user-plane-configuration/tx-array-carriers/name"; + } + description + "name of tx-array-carriers is notified at state change"; + } + leaf state{ + type leafref{ + path "/user-plane-configuration/tx-array-carriers/state"; + } + description + "state of tx-array-carriers is notified at state change"; + } + } + } + + grouping rx-array-notification-group { + description + "Grouping for rx-array for notification"; + + list rx-array-carriers{ + key name; + description + "Notification used to inform about state change of rx-array-carriers"; + leaf name{ + type leafref{ + path "/user-plane-configuration/rx-array-carriers/name"; + } + description + "name of rx-array-carriers is notified at state change"; + } + leaf state{ + type leafref{ + path "/user-plane-configuration/rx-array-carriers/state"; + } + description + "state of rx-array-carriers is notified at state change"; + } + } + } + +// top level container + + container user-plane-configuration { + description "top level container for user plane configuration"; + + uses uplane-conf-group; + uses general-config; + } + + //notification statement + notification tx-array-carriers-state-change { + description + "Notification used to inform about state change of tx-array-carriers"; + uses tx-array-notification-group; + } + notification rx-array-carriers-state-change { + description + "Notification used to inform about state change of tx-array-carriers"; + + uses rx-array-notification-group; + } +} From e79c79b82eb31e028710e4d8e745d98e04c46d34 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 17:16:55 +0100 Subject: [PATCH 17/27] Add RPC for M-plane - generate CU-planes RU configuration based on the loaded yang models and DU config file - not yet implemented for libyang and libnetconf2 v1 --- radio/fhi_72/mplane/CMakeLists.txt | 2 + radio/fhi_72/mplane/config-mplane.c | 70 ++++ radio/fhi_72/mplane/config-mplane.h | 30 ++ radio/fhi_72/mplane/init-mplane.c | 6 + radio/fhi_72/mplane/yang/create-yang-config.c | 392 ++++++++++++++++++ radio/fhi_72/mplane/yang/create-yang-config.h | 32 ++ 6 files changed, 532 insertions(+) create mode 100644 radio/fhi_72/mplane/config-mplane.c create mode 100644 radio/fhi_72/mplane/config-mplane.h create mode 100644 radio/fhi_72/mplane/yang/create-yang-config.c create mode 100644 radio/fhi_72/mplane/yang/create-yang-config.h diff --git a/radio/fhi_72/mplane/CMakeLists.txt b/radio/fhi_72/mplane/CMakeLists.txt index 183121e40a..a6bd7e62d7 100644 --- a/radio/fhi_72/mplane/CMakeLists.txt +++ b/radio/fhi_72/mplane/CMakeLists.txt @@ -30,9 +30,11 @@ target_sources(oran_fhlib_5g_mplane PRIVATE rpc-send-recv.c get-mplane.c subscribe-mplane.c + config-mplane.c ru-mplane-api.c xml/get-xml.c yang/get-yang.c + yang/create-yang-config.c ) pkg_check_modules(libyang REQUIRED libyang) diff --git a/radio/fhi_72/mplane/config-mplane.c b/radio/fhi_72/mplane/config-mplane.c new file mode 100644 index 0000000000..7a66c6ec7a --- /dev/null +++ b/radio/fhi_72/mplane/config-mplane.c @@ -0,0 +1,70 @@ +/* + * 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 "config-mplane.h" +#include "rpc-send-recv.h" +#include "yang/get-yang.h" +#include "yang/create-yang-config.h" +#include "common/utils/assertions.h" + +#include +#include + +bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const openair0_config_t *oai, const size_t num_rus) +{ + int timeout = CLI_RPC_REPLY_TIMEOUT; + struct nc_rpc *rpc; + NC_WD_MODE wd = NC_WD_ALL; + NC_PARAMTYPE param = NC_PARAMTYPE_CONST; + NC_DATASTORE target = NC_DATASTORE_CANDIDATE; + NC_RPC_EDIT_DFLTOP op = NC_RPC_EDIT_DFLTOP_MERGE; + NC_RPC_EDIT_TESTOPT test = NC_RPC_EDIT_TESTOPT_UNKNOWN; + NC_RPC_EDIT_ERROPT err = NC_RPC_EDIT_ERROPT_UNKNOWN; + + bool success = false; + + struct ly_ctx *ctx = NULL; + success = load_yang_models(ru_session, buffer, &ctx); + AssertError(success, return false, "[MPLANE] Unable to continue.\n"); + + char *content = NULL; + success = configure_ru_from_yang(&ctx, ru_session, oai, num_rus, &content); + AssertError(success, return false, "[MPLANE] Unable to create content for RPC.\n"); + + MP_LOG_I("RPC request to RU \"%s\" = :\n%s\n", ru_session->ru_ip_add, content); + rpc = nc_rpc_edit(target, op, test, err, content, param); + AssertError(rpc != NULL, return false, "[MPLANE] RPC creation failed.\n"); + + success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL); + AssertError(success, return false, "[MPLANE] Failed to edit configuration for the candidate datastore.\n"); + + MP_LOG_I("Successfully edited the candidate datastore for RU \"%s\".\n", ru_session->ru_ip_add); + + nc_rpc_free(rpc); + free(content); +#ifdef MPLANE_V1 + ly_ctx_destroy(ctx, NULL); +#elif defined MPLANE_V2 + ly_ctx_destroy(ctx); +#endif + + return true; +} diff --git a/radio/fhi_72/mplane/config-mplane.h b/radio/fhi_72/mplane/config-mplane.h new file mode 100644 index 0000000000..aecf8dc348 --- /dev/null +++ b/radio/fhi_72/mplane/config-mplane.h @@ -0,0 +1,30 @@ +/* + * 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 + */ + +#ifndef CONFIGURE_MPLANE_H +#define CONFIGURE_MPLANE_H + +#include "ru-mplane-api.h" +#include "radio/COMMON/common_lib.h" + +bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const openair0_config_t *oai, const size_t num_rus); + +#endif /* CONFIGURE_MPLANE_H */ diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index add3916f4d..5966012945 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -23,6 +23,7 @@ #include "radio/fhi_72/oran-params.h" #include "get-mplane.h" #include "subscribe-mplane.h" +#include "config-mplane.h" #include "xml/get-xml.h" #include @@ -174,6 +175,11 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz success = get_uplane_info(operational_ds, &ru_session->ru_mplane_config); AssertError(success, return false, "[MPLANE] Unable to get U-plane info from RU operational datastore.\n"); + if (ru_session->ru_notif.ptp_state) { + success = edit_config_mplane(ru_session, operational_ds, oai, num_rus); + AssertError(success, return false, "[MPLANE] Unable to edit the RU configuration.\n"); + } + free(operational_ds); free(watchdog_answer); diff --git a/radio/fhi_72/mplane/yang/create-yang-config.c b/radio/fhi_72/mplane/yang/create-yang-config.c new file mode 100644 index 0000000000..7276b9fae0 --- /dev/null +++ b/radio/fhi_72/mplane/yang/create-yang-config.c @@ -0,0 +1,392 @@ +/* + * 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 "create-yang-config.h" +#include "common/utils/nr/nr_common.h" + +#define VERIFY_SUCCESS(var, message, args...) AssertError(var, return false, message, ##args) + +#ifdef MPLANE_V2 +static bool create_cu_interface_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root) +{ + LY_ERR ret = LY_SUCCESS; + + ret = lyd_new_path(NULL, *ctx, "/ietf-interfaces:interfaces", NULL, 0, root); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"interfaces\" node.\n"); + + struct lyd_node *interface_node = NULL; + ret = lyd_new_list(*root, NULL, "interface", 0, &interface_node, int_name); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"interface\" node.\n"); + + struct lyd_node *type_node = NULL; + ret = lyd_new_term(interface_node, NULL, "type", "iana-if-type:l2vlan", 0, &type_node); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"type\" node.\n"); + + ret = lyd_new_term(interface_node, NULL, "enabled", "true", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"enabled\" node.\n"); + + const struct lys_module *oran_int_mod = ly_ctx_get_module_implemented(*ctx, "o-ran-interfaces"); + VERIFY_SUCCESS(oran_int_mod != NULL, "[MPLANE] Failed to get \"o-ran-interfaces\" module.\n"); + + struct lyd_node *base_int = NULL; + ret = lyd_new_term(interface_node, oran_int_mod, "base-interface", ru_session->ru_mplane_config.interface_name, 0, &base_int); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"base-interface\" node with name \"%s\".\n", ru_session->ru_mplane_config.interface_name); + + struct lyd_node *vlan_id = NULL; + char vlan_tag_str[8]; + snprintf(vlan_tag_str, sizeof(vlan_tag_str), "%d", ru_session->ru_mplane_config.vlan_tag[idx]); + ret = lyd_new_term(interface_node, oran_int_mod, "vlan-id", vlan_tag_str, 0, &vlan_id); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"vlan-id\" node with \"%d\".\n", ru_session->ru_mplane_config.vlan_tag[idx]); + + struct lyd_node *ru_mac_addr = NULL; + ret = lyd_new_term(interface_node, oran_int_mod, "mac-address", ru_session->xran_mplane.ru_mac_addr, 0, &ru_mac_addr); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"mac-address\" node with \"%s\".\n", ru_session->xran_mplane.ru_mac_addr); + + return true; +} + +static bool create_proc_elem_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root) +{ + LY_ERR ret = LY_SUCCESS; + + ret = lyd_new_path(NULL, *ctx, "/o-ran-processing-element:processing-elements", NULL, 0, root); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"processing-elements\" node.\n"); + + ret = lyd_new_term(*root, NULL, "transport-session-type", "ETH-INTERFACE", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"transport-session-type\" node.\n"); + + struct lyd_node *ru_elem_node = NULL; + char plane_name[8]; + snprintf(plane_name, sizeof(plane_name), "PLANE_%ld", idx); + ret = lyd_new_list(*root, NULL, "ru-elements", 0, &ru_elem_node, plane_name); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ru-elements\" node.\n"); + + struct lyd_node *transp_flow = NULL; + ret = lyd_new_inner(ru_elem_node, NULL, "transport-flow", 0, &transp_flow); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"transport-flow\" node.\n"); + + ret = lyd_new_term(transp_flow, NULL, "interface-name", int_name, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"interface-name\" node.\n"); + + struct lyd_node *eth_flow = NULL; + ret = lyd_new_inner(transp_flow, NULL, "eth-flow", 0, ð_flow); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"eth-flow\" node.\n"); + + char vlan_tag_str[8]; + snprintf(vlan_tag_str, sizeof(vlan_tag_str), "%d", ru_session->ru_mplane_config.vlan_tag[idx]); + ret = lyd_new_term(eth_flow, NULL, "vlan-id", vlan_tag_str, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"vlan-id\" node.\n"); + + ret = lyd_new_term(eth_flow, NULL, "ru-mac-address", ru_session->xran_mplane.ru_mac_addr, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ru-mac-address\" node.\n"); + + ret = lyd_new_term(eth_flow, NULL, "o-du-mac-address", ru_session->ru_mplane_config.du_mac_addr[idx], 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"o-du-mac-address\" node.\n"); + + return true; +} + +static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx, struct lyd_node **root) +{ + LY_ERR ret = LY_SUCCESS; + + ret = lyd_new_term(*root, NULL, "cp-length", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-length\" node.\n"); + + ret = lyd_new_term(*root, NULL, "cp-length-other", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-length-other\" node.\n"); + + // to we actually store this from DU config file? + ret = lyd_new_term(*root, NULL, "offset-to-absolute-frequency-center", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"offset-to-absolute-frequency-center\" node.\n"); + + struct lyd_node *compression_node = NULL; + ret = lyd_new_inner(*root, NULL, "compression", 0, &compression_node); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression\" node.\n"); + + char iq_width_str[8]; + snprintf(iq_width_str, sizeof(iq_width_str), "%d", xran_mplane->iq_width); + ret = lyd_new_term(compression_node, NULL, "iq-bitwidth", iq_width_str, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"iq-bitwidth\" node.\n"); + + if (xran_mplane->iq_width < 16) { + ret = lyd_new_term(compression_node, NULL, "compression-type", "STATIC", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression-type\" node.\n"); + + // ret = lyd_new_term(compression_node, NULL, "compression-method", "BLOCK_FLOATING_POINT", 0, NULL); + // VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression-method\" node.\n"); + } + + struct lyd_node *eaxc_conf = NULL; + ret = lyd_new_inner(*root, NULL, "e-axcid", 0, &eaxc_conf); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"e-axcid\" node.\n"); + + char eaxc_id[8]; + snprintf(eaxc_id, sizeof(eaxc_id), "%ld", idx); + ret = lyd_new_term(eaxc_conf, NULL, "eaxc-id", eaxc_id, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"eaxc-id\" node.\n"); + + char du_port_bitmask[16]; + snprintf(du_port_bitmask, sizeof(du_port_bitmask), "%d", xran_mplane->du_port_bitmask); + ret = lyd_new_term(eaxc_conf, NULL, "o-du-port-bitmask", du_port_bitmask, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"o-du-port-bitmask\" node.\n"); + + char band_sector_bitmask[8]; + snprintf(band_sector_bitmask, sizeof(band_sector_bitmask), "%d", xran_mplane->band_sector_bitmask); + ret = lyd_new_term(eaxc_conf, NULL, "band-sector-bitmask", band_sector_bitmask, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"band-sector-bitmask\" node.\n"); + + char ccid_bitmask[8]; + snprintf(ccid_bitmask, sizeof(ccid_bitmask), "%d", xran_mplane->ccid_bitmask); + ret = lyd_new_term(eaxc_conf, NULL, "ccid-bitmask", ccid_bitmask, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ccid-bitmask\" node.\n"); + + char ru_port_bitmask[8]; + snprintf(ru_port_bitmask, sizeof(ru_port_bitmask), "%d", xran_mplane->ru_port_bitmask); + ret = lyd_new_term(eaxc_conf, NULL, "ru-port-bitmask", ru_port_bitmask, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ru-port-bitmask\" node.\n"); + + return true; +} + +static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, const char *u_proc_elem, struct lyd_node **root) +{ + LY_ERR ret = LY_SUCCESS; + bool success = true; + + ret = lyd_new_path(NULL, *ctx, "/o-ran-uplane-conf:user-plane-configuration", NULL, 0, root); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"user-plane-configuration\" node.\n"); + + if (ru_session->ru_mplane_config.rx_carriers.num != 1 || ru_session->ru_mplane_config.tx_carriers.num !=1) + MP_LOG_I("Only one carrier supported at the moment.\n"); + + // RX carriers + struct lyd_node *rx_carrier_node = NULL; + ret = lyd_new_list(*root, NULL, "rx-array-carriers", 0, &rx_carrier_node, ru_session->ru_mplane_config.rx_carriers.name[0]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"rx-array-carriers\" node.\n"); + + char rx_freq[16]; + snprintf(rx_freq, sizeof(rx_freq), "%.0f", oai->rx_freq[0]); + ret = lyd_new_term(rx_carrier_node, NULL, "center-of-channel-bandwidth", rx_freq, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"center-of-channel-bandwidth\" node.\n"); + + char rx_arfcn[16]; + snprintf(rx_arfcn, sizeof(rx_arfcn), "%d", to_nrarfcn(oai->nr_band, oai->rx_freq[0], oai->nr_scs_for_raster, oai->rx_bw)); + ret = lyd_new_term(rx_carrier_node, NULL, "absolute-frequency-center", rx_arfcn, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"absolute-frequency-center\" node.\n"); + + char rx_bw[16]; + snprintf(rx_bw, sizeof(rx_bw), "%.0f", oai->rx_bw); + ret = lyd_new_term(rx_carrier_node, NULL, "channel-bandwidth", rx_bw, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"channel-bandwidth\" node.\n"); + + ret = lyd_new_term(rx_carrier_node, NULL, "downlink-radio-frame-offset", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"downlink-radio-frame-offset\" node.\n"); + + ret = lyd_new_term(rx_carrier_node, NULL, "downlink-sfn-offset", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"downlink-sfn-offset\" node.\n"); + + // oai->rx_gain_offset is this the correction? if yes, test it later + ret = lyd_new_term(rx_carrier_node, NULL, "gain-correction", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"gain-correction\" node.\n"); + + ret = lyd_new_term(rx_carrier_node, NULL, "n-ta-offset", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"n-ta-offset\" node.\n"); + + ret = lyd_new_term(rx_carrier_node, NULL, "active", "ACTIVE", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"active\" node.\n"); + + // TX carriers + struct lyd_node *tx_carrier_node = NULL; + ret = lyd_new_list(*root, NULL, "tx-array-carriers", 0, &tx_carrier_node, ru_session->ru_mplane_config.tx_carriers.name[0]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"tx-array-carriers\" node.\n"); + + char tx_freq[16]; + snprintf(tx_freq, sizeof(tx_freq), "%.0f", oai->tx_freq[0]); + ret = lyd_new_term(tx_carrier_node, NULL, "center-of-channel-bandwidth", tx_freq, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"center-of-channel-bandwidth\" node.\n"); + + char tx_arfcn[16]; + snprintf(tx_arfcn, sizeof(tx_arfcn), "%d", to_nrarfcn(oai->nr_band, oai->tx_freq[0], oai->nr_scs_for_raster, oai->tx_bw)); + ret = lyd_new_term(tx_carrier_node, NULL, "absolute-frequency-center", tx_arfcn, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"absolute-frequency-center\" node.\n"); + + char tx_bw[16]; + snprintf(tx_bw, sizeof(tx_bw), "%.0f", oai->tx_bw); + ret = lyd_new_term(tx_carrier_node, NULL, "channel-bandwidth", tx_bw, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"channel-bandwidth\" node.\n"); + + // oai->tx_gain to be tested + ret = lyd_new_term(tx_carrier_node, NULL, "gain", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"gain\" node.\n"); + + ret = lyd_new_term(tx_carrier_node, NULL, "downlink-radio-frame-offset", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"downlink-radio-frame-offset\" node.\n"); + + ret = lyd_new_term(tx_carrier_node, NULL, "downlink-sfn-offset", "0", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"downlink-sfn-offset\" node.\n"); + + ret = lyd_new_term(tx_carrier_node, NULL, "active", "ACTIVE", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"active\" node.\n"); + + // PUSCH & PRACH endpoints + const size_t num_rx_ch = oai->rx_num_channels / num_rus; + for (size_t i = 0; i < num_rx_ch; i++) { + struct lyd_node *pusch_node = NULL; + ret = lyd_new_list(*root, NULL, "low-level-rx-endpoints", 0, &pusch_node, ru_session->ru_mplane_config.rx_endpoints.name[i]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoints\" node.\n"); + + success = fill_uplane_ch_v2(&ru_session->xran_mplane, i, &pusch_node); + VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-rx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.rx_endpoints.name[i]); + + const size_t prach_endpoint_name_offset = i + (ru_session->ru_mplane_config.rx_endpoints.num / 2); + struct lyd_node *prach_node = NULL; + ret = lyd_new_list(*root, NULL, "low-level-rx-endpoints", 0, &prach_node, ru_session->ru_mplane_config.rx_endpoints.name[prach_endpoint_name_offset]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoints\" node.\n"); + + success = fill_uplane_ch_v2(&ru_session->xran_mplane, i + ru_session->xran_mplane.prach_offset, &prach_node); + VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-rx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.rx_endpoints.name[prach_endpoint_name_offset]); + } + + // PDSCH endpoints + const size_t num_tx_ch = oai->tx_num_channels / num_rus; + for (size_t i = 0; i < num_tx_ch; i++) { + struct lyd_node *pdsch_node = NULL; + ret = lyd_new_list(*root, NULL, "low-level-tx-endpoints", 0, &pdsch_node, ru_session->ru_mplane_config.tx_endpoints.name[i]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-tx-endpoints\" node.\n"); + + success = fill_uplane_ch_v2(&ru_session->xran_mplane, i, &pdsch_node); + VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-tx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.tx_endpoints.name[i]); + } + + // PUSCH and PRACH links + for (size_t i = 0; i < num_rx_ch; i++) { + // PUSCH + struct lyd_node *pusch_link_node = NULL; + char pusch_link[16]; + snprintf(pusch_link, sizeof(pusch_link), "%s%ld", "PuschLink", i); + ret = lyd_new_list(*root, NULL, "low-level-rx-links", 0, &pusch_link_node, pusch_link); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-links\" node.\n"); + + ret = lyd_new_term(pusch_link_node, NULL, "processing-element", u_proc_elem, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"processing-element\" node.\n"); + + ret = lyd_new_term(pusch_link_node, NULL, "rx-array-carrier", ru_session->ru_mplane_config.rx_carriers.name[0], 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"rx-array-carrier\" node.\n"); + + ret = lyd_new_term(pusch_link_node, NULL, "low-level-rx-endpoint", ru_session->ru_mplane_config.rx_endpoints.name[i], 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoint\" node.\n"); + + // PRACH + struct lyd_node *prach_link_node = NULL; + char prach_link[16]; + snprintf(prach_link, sizeof(prach_link), "%s%ld", "PrachLink", i); + ret = lyd_new_list(*root, NULL, "low-level-rx-links", 0, &prach_link_node, prach_link); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-links\" node.\n"); + + ret = lyd_new_term(prach_link_node, NULL, "processing-element", u_proc_elem, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"processing-element\" node.\n"); + + ret = lyd_new_term(prach_link_node, NULL, "rx-array-carrier", ru_session->ru_mplane_config.rx_carriers.name[0], 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"rx-array-carrier\" node.\n"); + + const size_t prach_endpoint_name_offset = i + (ru_session->ru_mplane_config.rx_endpoints.num / 2); + ret = lyd_new_term(prach_link_node, NULL, "low-level-rx-endpoint", ru_session->ru_mplane_config.rx_endpoints.name[prach_endpoint_name_offset], 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoint\" node.\n"); + } + + // PDSCH links + for (size_t i = 0; i < num_tx_ch; i++) { + struct lyd_node *pdsch_link_node = NULL; + char pdsch_link[16]; + snprintf(pdsch_link, sizeof(pdsch_link), "%s%ld", "PdschLink", i); + ret = lyd_new_list(*root, NULL, "low-level-tx-links", 0, &pdsch_link_node, pdsch_link); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-tx-links\" node.\n"); + + ret = lyd_new_term(pdsch_link_node, NULL, "processing-element", u_proc_elem, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"processing-element\" node.\n"); + + ret = lyd_new_term(pdsch_link_node, NULL, "tx-array-carrier", ru_session->ru_mplane_config.tx_carriers.name[0], 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"tx-array-carrier\" node.\n"); + + ret = lyd_new_term(pdsch_link_node, NULL, "low-level-tx-endpoint", ru_session->ru_mplane_config.tx_endpoints.name[i], 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-tx-endpoint\" node.\n"); + } + + return true; +} +#endif + +bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result) +{ + bool success = false; + +#ifdef MPLANE_V1 + VERIFY_SUCCESS(success, "[MPLANE] To be implemented and tested.\n"); +#elif defined MPLANE_V2 + const ru_mplane_config_t *ru_config = &ru_session->ru_mplane_config; + size_t num_cu_planes = ru_config->num_cu_planes; + if (num_cu_planes == 2 && ru_config->vlan_tag[0] == ru_config->vlan_tag[1]) { + MP_LOG_I("The VLAN tags for C and U plane for the RU \"%s\" are the same. Therefore, configuring one common interface and one processing element.\n", ru_session->ru_ip_add); + num_cu_planes = 1; + } + + struct lyd_node *all_merge = NULL; + LY_ERR ret = LY_SUCCESS; + + for (size_t i = 0; i < num_cu_planes; i++) { + // + struct lyd_node *cu_interface = NULL; + char int_name[12]; + snprintf(int_name, sizeof(int_name), "INTERFACE_%ld", i); + success = create_cu_interface_v2(ctx, ru_session, i, int_name, &cu_interface); + VERIFY_SUCCESS(success, "[MPLANE] Cannot create CU-plane interface.\n"); + + // + struct lyd_node *proc_elem = NULL; + success = create_proc_elem_v2(ctx, ru_session, i, int_name, &proc_elem); + VERIFY_SUCCESS(success, "[MPLANE] Cannot create CU-plane processing element.\n"); + + ret = lyd_merge_siblings(&all_merge, cu_interface, 0); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Cannot merge CU-plane interface.\n"); + ret = lyd_merge_siblings(&all_merge, proc_elem, 0); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Cannot merge processing element.\n"); + + lyd_free_tree(cu_interface); + lyd_free_tree(proc_elem); + } + + // + struct lyd_node *uplane_conf = NULL; + success = create_uplane_conf_v2(ctx, ru_session, oai, num_rus, "PLANE_0", &uplane_conf); + VERIFY_SUCCESS(success, "[MPLANE] Cannot create U-plane configuration.\n"); + + ret = lyd_merge_siblings(&uplane_conf, all_merge, 0); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Cannot merge CU-plane interface, processing element and U-plane configuration.\n"); + + lyd_print_mem(result, uplane_conf, LYD_XML, LYD_PRINT_WITHSIBLINGS); + + lyd_free_siblings(all_merge); + lyd_free_siblings(uplane_conf); +#endif + + return true; +} diff --git a/radio/fhi_72/mplane/yang/create-yang-config.h b/radio/fhi_72/mplane/yang/create-yang-config.h new file mode 100644 index 0000000000..9e06bdc923 --- /dev/null +++ b/radio/fhi_72/mplane/yang/create-yang-config.h @@ -0,0 +1,32 @@ +/* + * 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 + */ + +#ifndef CREATE_MPLANE_YANG_CONFIG_H +#define CREATE_MPLANE_YANG_CONFIG_H + +#include "../ru-mplane-api.h" +#include "radio/COMMON/common_lib.h" + +#include + +bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result); + +#endif /* CREATE_MPLANE_YANG_CONFIG_H */ From b478930a047f86def402ff5a732f314fba5f2bbf Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 17:22:41 +0100 Subject: [PATCH 18/27] Add RPC for M-plane --- radio/fhi_72/mplane/config-mplane.c | 23 +++++++++++++++++++++++ radio/fhi_72/mplane/config-mplane.h | 2 ++ radio/fhi_72/mplane/init-mplane.c | 3 +++ 3 files changed, 28 insertions(+) diff --git a/radio/fhi_72/mplane/config-mplane.c b/radio/fhi_72/mplane/config-mplane.c index 7a66c6ec7a..94d3bbe49e 100644 --- a/radio/fhi_72/mplane/config-mplane.c +++ b/radio/fhi_72/mplane/config-mplane.c @@ -68,3 +68,26 @@ bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const open return true; } + +bool validate_config_mplane(ru_session_t *ru_session) +{ + int timeout = CLI_RPC_REPLY_TIMEOUT; + struct nc_rpc *rpc; + NC_WD_MODE wd = NC_WD_ALL; + NC_PARAMTYPE param = NC_PARAMTYPE_CONST; + char *src_start = NULL; + NC_DATASTORE source = NC_DATASTORE_CANDIDATE; + + MP_LOG_I("RPC request to RU \"%s\" = candidate datastore.\n", ru_session->ru_ip_add); + rpc = nc_rpc_validate(source, src_start, param); + AssertError(rpc != NULL, return false, "[MPLANE] RPC creation failed.\n"); + + bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL); + AssertError(success, return false, "[MPLANE] Failed to validate candidate datastore.\n"); + + MP_LOG_I("Successfully validated candidate datastore for RU \"%s\".\n", ru_session->ru_ip_add); + + nc_rpc_free(rpc); + + return true; +} diff --git a/radio/fhi_72/mplane/config-mplane.h b/radio/fhi_72/mplane/config-mplane.h index aecf8dc348..ba3c926954 100644 --- a/radio/fhi_72/mplane/config-mplane.h +++ b/radio/fhi_72/mplane/config-mplane.h @@ -27,4 +27,6 @@ bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const openair0_config_t *oai, const size_t num_rus); +bool validate_config_mplane(ru_session_t *ru_session); + #endif /* CONFIGURE_MPLANE_H */ diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index 5966012945..f3560850fe 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -178,6 +178,9 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz if (ru_session->ru_notif.ptp_state) { success = edit_config_mplane(ru_session, operational_ds, oai, num_rus); AssertError(success, return false, "[MPLANE] Unable to edit the RU configuration.\n"); + + success = validate_config_mplane(ru_session); + AssertError(success, return false, "[MPLANE] Unable to validate the RU configuration.\n"); } free(operational_ds); From f22bc5acc74e6b63f02cd0c3512f561ab0fe6bdd Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 17:25:39 +0100 Subject: [PATCH 19/27] Add RPC for M-plane --- radio/fhi_72/mplane/config-mplane.c | 24 ++++++++++++++++++++++++ radio/fhi_72/mplane/config-mplane.h | 2 ++ radio/fhi_72/mplane/init-mplane.c | 3 +++ 3 files changed, 29 insertions(+) diff --git a/radio/fhi_72/mplane/config-mplane.c b/radio/fhi_72/mplane/config-mplane.c index 94d3bbe49e..69ff1fd2b3 100644 --- a/radio/fhi_72/mplane/config-mplane.c +++ b/radio/fhi_72/mplane/config-mplane.c @@ -91,3 +91,27 @@ bool validate_config_mplane(ru_session_t *ru_session) return true; } + +bool commit_config_mplane(ru_session_t *ru_session) +{ + int timeout = CLI_RPC_REPLY_TIMEOUT; + struct nc_rpc *rpc; + NC_WD_MODE wd = NC_WD_ALL; + NC_PARAMTYPE param = NC_PARAMTYPE_CONST; + int confirmed = 0; + int32_t confirm_timeout = 0; + char *persist = NULL, *persist_id = NULL; + + MP_LOG_I("RPC request to RU \"%s\" = candidate datastore.\n", ru_session->ru_ip_add); + rpc = nc_rpc_commit(confirmed, confirm_timeout, persist, persist_id, param); + AssertError(rpc != NULL, return false, "[MPLANE] RPC creation failed.\n"); + + bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL); + AssertError(success, return false, "[MPLANE] Failed to commit candidate datastore.\n"); + + MP_LOG_I("Successfully commited CU-planes configuration into running datastore for RU \"%s\".\n", ru_session->ru_ip_add); + + nc_rpc_free(rpc); + + return true; +} diff --git a/radio/fhi_72/mplane/config-mplane.h b/radio/fhi_72/mplane/config-mplane.h index ba3c926954..c8451ca8a0 100644 --- a/radio/fhi_72/mplane/config-mplane.h +++ b/radio/fhi_72/mplane/config-mplane.h @@ -29,4 +29,6 @@ bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const open bool validate_config_mplane(ru_session_t *ru_session); +bool commit_config_mplane(ru_session_t *ru_session); + #endif /* CONFIGURE_MPLANE_H */ diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index f3560850fe..352a564cec 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -181,6 +181,9 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz success = validate_config_mplane(ru_session); AssertError(success, return false, "[MPLANE] Unable to validate the RU configuration.\n"); + + success = commit_config_mplane(ru_session); + AssertError(success, return false, "[MPLANE] Unable to commit the RU configuration.\n"); } free(operational_ds); From 430026f1ecc2f14061cf3e0dceec7b20bcd5f7e8 Mon Sep 17 00:00:00 2001 From: Teodora Date: Tue, 11 Feb 2025 12:35:52 +0100 Subject: [PATCH 20/27] Wait until RUs are ready and add RPC for M-plane - if RU(s) are not well configured, disconnect immediately and stop the DU - if all RUs are well configured, proceed with waiting until ready. The RU is ready when the carriers are activated. Either the RU already has preconfigured carriers (previous M-plane client configured), or the DU has to wait until receives the notifications. --- radio/fhi_72/mplane/connect-mplane.c | 16 +++++++++++ radio/fhi_72/mplane/connect-mplane.h | 2 ++ radio/fhi_72/mplane/init-mplane.c | 12 ++++++++ radio/fhi_72/mplane/ru-mplane-api.h | 1 + radio/fhi_72/mplane/subscribe-mplane.c | 2 ++ radio/fhi_72/oran_isolate.c | 40 ++++++++++++++++++++++++++ 6 files changed, 73 insertions(+) diff --git a/radio/fhi_72/mplane/connect-mplane.c b/radio/fhi_72/mplane/connect-mplane.c index 7f4e5e40e6..08b758bef1 100644 --- a/radio/fhi_72/mplane/connect-mplane.c +++ b/radio/fhi_72/mplane/connect-mplane.c @@ -55,3 +55,19 @@ bool connect_mplane(ru_session_t *ru_session) return true; } + +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("Disconnecting from RU \"%s\".\n", ru_session->ru_ip_add); + nc_session_free(ru_session->session, NULL); + ru_session->session = NULL; + } + + nc_client_destroy(); +} diff --git a/radio/fhi_72/mplane/connect-mplane.h b/radio/fhi_72/mplane/connect-mplane.h index 5283e6ef75..e46aa60f19 100644 --- a/radio/fhi_72/mplane/connect-mplane.h +++ b/radio/fhi_72/mplane/connect-mplane.h @@ -26,4 +26,6 @@ bool connect_mplane(ru_session_t *ru_session); +void disconnect_mplane(void *rus_disconnect); + #endif /* CONNECT_MPLANE_H */ diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index 352a564cec..39e8cfb995 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -186,6 +186,18 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz AssertError(success, return false, "[MPLANE] Unable to commit the RU configuration.\n"); } + 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; + } + free(operational_ds); free(watchdog_answer); diff --git a/radio/fhi_72/mplane/ru-mplane-api.h b/radio/fhi_72/mplane/ru-mplane-api.h index 1afabd4d23..70857adea6 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.h +++ b/radio/fhi_72/mplane/ru-mplane-api.h @@ -35,6 +35,7 @@ typedef struct { bool ptp_state; bool rx_carrier_state; bool tx_carrier_state; + bool config_change; // to be extended with any notification callback } ru_notif_t; diff --git a/radio/fhi_72/mplane/subscribe-mplane.c b/radio/fhi_72/mplane/subscribe-mplane.c index d96d367d35..9a8e28c4c1 100644 --- a/radio/fhi_72/mplane/subscribe-mplane.c +++ b/radio/fhi_72/mplane/subscribe-mplane.c @@ -79,6 +79,8 @@ static void recv_notif_v2(struct lyd_node_inner *op, ru_notif_t *answer) } else { // "DISABLED" or "BUSY" answer->tx_carrier_state = false; } + } 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 8104b1a2c2..a5e2d5baf7 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -49,6 +49,7 @@ typedef struct { rru_config_msg_type_t last_msg; int capabilities_sent; void *oran_priv; + void *mplane_priv; } oran_eth_state_t; notifiedFIFO_t oran_sync_fifo; @@ -81,6 +82,10 @@ int trx_oran_stop(openair0_device *device) printf("ORAN: %s\n", __FUNCTION__); oran_eth_state_t *s = device->priv; xran_stop(s->oran_priv); +#ifdef OAI_MPLANE + printf("[MPLANE] Stopping M-plane.\n"); + disconnect_mplane(s->mplane_priv); +#endif return (0); } @@ -304,6 +309,41 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d } ru_configured[i] = manage_ru(ru_session, openair0_cfg, ru_session_list.num_rus); } + + bool all_ok = true; + bool ru_ready[ru_session_list.num_rus]; + for (size_t i = 0; i < ru_session_list.num_rus; i++) { + if (!ru_configured[i]) { + MP_LOG_I("RU with IP %s couldn't be configured.\n", ru_session_list.ru_session[i].ru_ip_add); + all_ok = false; + } + ru_ready[i] = false; + } + + if (!all_ok) { + disconnect_mplane((void *)&ru_session_list); + AssertFatal(false, "[MPLANE] Stopping M-plane.\n"); + } + + while (true) { + sleep(1); + 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) { + MP_LOG_I("RU \"%s\" is now ready.\n", ru_session->ru_ip_add); + ru_ready[i] = true; + } else { + all_rus_ready = false; + break; + } + } + if (all_rus_ready) { + break; + } + } + + eth->mplane_priv = (void *)&ru_session_list; #else success = get_xran_config(openair0_cfg, &fh_init, fh_config); AssertFatal(success, "cannot get configuration for xran\n"); From d5fceb8e1fd3d6599d938531caa7799b656376f1 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 17:46:08 +0100 Subject: [PATCH 21/27] Parsing RU M-plane info to xran --- radio/fhi_72/oran-config.c | 132 +++++++++++++++++++++++++++++------- radio/fhi_72/oran-config.h | 2 +- radio/fhi_72/oran_isolate.c | 5 +- 3 files changed, 113 insertions(+), 26 deletions(-) diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index ba8fb2fcea..71804c5298 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -32,6 +32,10 @@ #include "stdio.h" #include "string.h" +#ifdef OAI_MPLANE +#include "mplane/ru-mplane-api.h" +#endif + static void print_fh_eowd_cmn(unsigned index, const struct xran_ecpri_del_meas_cmn *eowd_cmn) { printf("\ @@ -522,6 +526,38 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in return true; } +#ifdef OAI_MPLANE +static bool set_fh_eaxcid_conf_mplane(struct xran_eaxcid_config *eaxcid_conf, enum xran_category cat, const ru_session_list_t *ru_session_list) +{ + xran_mplane_t *xran_mplane = &ru_session_list->ru_session[0].xran_mplane; + switch (cat) { + case XRAN_CATEGORY_A: + eaxcid_conf->mask_cuPortId = xran_mplane->du_port_bitmask; + eaxcid_conf->mask_bandSectorId = xran_mplane->band_sector_bitmask; + eaxcid_conf->mask_ccId = xran_mplane->ccid_bitmask; + eaxcid_conf->mask_ruPortId = xran_mplane->ru_port_bitmask; + eaxcid_conf->bit_cuPortId = xran_mplane->du_port; + eaxcid_conf->bit_bandSectorId = xran_mplane->band_sector; // total number of band sectors supported by O-RU should be retrieved by M-plane - && + eaxcid_conf->bit_ccId = xran_mplane->ccid; // total number of CC supported by O-RU should be retrieved by M-plane - + eaxcid_conf->bit_ruPortId = xran_mplane->ru_port; + break; + case XRAN_CATEGORY_B: + eaxcid_conf->mask_cuPortId = 0xf000; + eaxcid_conf->mask_bandSectorId = 0x0c00; + eaxcid_conf->mask_ccId = 0x0300; + eaxcid_conf->mask_ruPortId = 0x000f; + eaxcid_conf->bit_cuPortId = 12; + eaxcid_conf->bit_bandSectorId = 10; + eaxcid_conf->bit_ccId = 8; + eaxcid_conf->bit_ruPortId = 0; + break; + default: + return false; + } + + return true; +} +#else static bool set_fh_eaxcid_conf(struct xran_eaxcid_config *eaxcid_conf, enum xran_category cat) { /* CUS specification, section 3.1.3.1.6 @@ -540,8 +576,8 @@ static bool set_fh_eaxcid_conf(struct xran_eaxcid_config *eaxcid_conf, enum xran eaxcid_conf->mask_ccId = 0x00f0; eaxcid_conf->mask_ruPortId = 0x000f; eaxcid_conf->bit_cuPortId = 0; - eaxcid_conf->bit_bandSectorId = 0; // total number of band sectors supported by O-RU should be retreived by M-plane - && - eaxcid_conf->bit_ccId = 0; // total number of CC supported by O-RU should be retreived by M-plane - + eaxcid_conf->bit_bandSectorId = 0; // total number of band sectors supported by O-RU should be retrieved by M-plane - && + eaxcid_conf->bit_ccId = 0; // total number of CC supported by O-RU should be retrieved by M-plane - eaxcid_conf->bit_ruPortId = 0; break; case XRAN_CATEGORY_B: @@ -560,6 +596,7 @@ static bool set_fh_eaxcid_conf(struct xran_eaxcid_config *eaxcid_conf, enum xran return true; } +#endif uint8_t *get_ether_addr(const char *addr, struct rte_ether_addr *ether_addr) { @@ -573,7 +610,7 @@ uint8_t *get_ether_addr(const char *addr, struct rte_ether_addr *ether_addr) return NULL; } -static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_cat) +static bool set_fh_init(void *mplane_api, struct xran_fh_init *fh_init, enum xran_category xran_cat) { memset(fh_init, 0, sizeof(*fh_init)); @@ -606,30 +643,46 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca const int nfh = sizeofArray(FHconfigs); config_getlist(config_get_if(), &FH_ConfigList, FHconfigs, nfh, aprefix); - int num_rus = FH_ConfigList.numelt; // based on the number of fh_config sections -> number of RUs +#ifdef OAI_MPLANE + ru_session_list_t *ru_session_list = (ru_session_list_t *)mplane_api; + int num_rus = ru_session_list->num_rus; + fh_init->xran_ports = num_rus; // since we use xran as O-DU, xran_ports is set to the number of RUs + if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus)) + return false; + if (!set_fh_eaxcid_conf_mplane(&fh_init->eAxCId_conf, xran_cat, ru_session_list)) + return false; + /* maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be + communicated in a single xRAN network layer transaction. Supported 1500 bytes and 9600 bytes (Jumbo Frame); + xran only checks if (MTU <= 1500), therefore setting any value > 1500, xran assumes 9600 value is used */ + fh_init->mtu = ru_session_list->ru_session[0].xran_mplane.mtu; // we suppose that each RU supports the same MTU size + int num_ru_addr = (fh_init->io_cfg.one_vf_cu_plane) ? num_rus : 2*num_rus; + fh_init->p_o_ru_addr = calloc(num_ru_addr, sizeof(struct rte_ether_addr)); + AssertFatal(fh_init->p_o_ru_addr != NULL, "out of memory\n"); + for (int i = 0; i < num_rus; i++) { + struct rte_ether_addr *ea = (struct rte_ether_addr *)fh_init->p_o_ru_addr; + for (int j = 0; j < num_ru_addr/num_rus; j++) { + if (get_ether_addr(ru_session_list->ru_session[i].xran_mplane.ru_mac_addr, &ea[i+j]) == NULL) { + printf("could not read ethernet address '%s' for RU!\n", ru_session_list->ru_session[i].xran_mplane.ru_mac_addr); + return false; + } + } + } +#else + int num_rus = FH_ConfigList.numelt; // based on the number of fh_config sections -> number of RUs + fh_init->xran_ports = num_rus; // since we use xran as O-DU, xran_ports is set to the number of RUs if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus)) return false; if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf, xran_cat)) return false; - - fh_init->xran_ports = num_rus; // since we use xran as O-DU, xran_ports is set to the number of RUs - fh_init->dpdkBasebandFecMode = 0; // DPDK Baseband FEC device mode (0-SW, 1-HW); not used in xran - fh_init->dpdkBasebandDevice = NULL; // DPDK Baseband device address; not used in xran - /* used to specify a unique prefix for shared memory, and files created by multiple DPDK processes; - it is necessary */ - fh_init->filePrefix = strdup(*gpd(fhip, nump, ORAN_CONFIG_FILE_PREFIX)->strptr); /* maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single xRAN network layer transaction. Supported 1500 bytes and 9600 bytes (Jumbo Frame); xran only checks if (MTU <= 1500), therefore setting any value > 1500, xran assumes 9600 value is used */ fh_init->mtu = *gpd(fhip, nump, ORAN_CONFIG_MTU)->uptr; - - fh_init->p_o_du_addr = NULL; // DPDK retreives DU MAC address within the xran library with rte_eth_macaddr_get() function - int num_ru_addr = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->numelt; fh_init->p_o_ru_addr = calloc(num_ru_addr, sizeof(struct rte_ether_addr)); - char **ru_addrs = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->strlistptr; AssertFatal(fh_init->p_o_ru_addr != NULL, "out of memory\n"); + char **ru_addrs = gpd(fhip, nump, ORAN_CONFIG_RU_ADDR)->strlistptr; for (int i = 0; i < num_ru_addr; ++i) { struct rte_ether_addr *ea = (struct rte_ether_addr *)fh_init->p_o_ru_addr; if (get_ether_addr(ru_addrs[i], &ea[i]) == NULL) { @@ -637,7 +690,14 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca return false; } } +#endif + fh_init->dpdkBasebandFecMode = 0; // DPDK Baseband FEC device mode (0-SW, 1-HW); not used in xran + fh_init->dpdkBasebandDevice = NULL; // DPDK Baseband device address; not used in xran + /* used to specify a unique prefix for shared memory, and files created by multiple DPDK processes; + it is necessary */ + fh_init->filePrefix = strdup(*gpd(fhip, nump, ORAN_CONFIG_FILE_PREFIX)->strptr); + fh_init->p_o_du_addr = NULL; // DPDK retreives DU MAC address within the xran library with rte_eth_macaddr_get() function fh_init->totalBfWeights = 0; // only used if id = O_RU (for emulation); C-plane extension types; section 5.4.6 of CUS spec #ifdef F_RELEASE @@ -656,7 +716,8 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca // this is a hack int g_kbar; -static bool set_fh_prach_config(const openair0_config_t *oai0, +static bool set_fh_prach_config(void *mplane_api, + const openair0_config_t *oai0, const uint32_t max_num_ant, const paramdef_t *prachp, int nprach, @@ -692,8 +753,13 @@ static bool set_fh_prach_config(const openair0_config_t *oai0, xran assumes PRACH offset >= max(Ntx, Nrx). However, we made a workaround that xran supports PRACH eAxC IDs same as PUSCH eAxC IDs. This is achieved with is_prach and filter_id parameters in the patch. Please note that this approach only applies to the RUs that support this functionality, e.g. LITEON RU. */ +#ifdef OAI_MPLANE + xran_mplane_t *xran_mplane = (xran_mplane_t *)mplane_api; + prach_config->eAxC_offset = xran_mplane->prach_offset; +#else uint8_t offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr; prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant; +#endif g_kbar = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_KBAR)->uptr; @@ -722,17 +788,24 @@ static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame return true; } -static bool set_fh_ru_config(const paramdef_t *rup, uint16_t fftSize, int nru, enum xran_category xran_cat, struct xran_ru_config *ru_config) +static bool set_fh_ru_config(void *mplane_api, const paramdef_t *rup, uint16_t fftSize, int nru, enum xran_category xran_cat, struct xran_ru_config *ru_config) { ru_config->xranTech = XRAN_RAN_5GNR; // 5GNR or LTE ru_config->xranCat = xran_cat; // mode: Catergory A or Category B ru_config->xranCompHdrType = XRAN_COMP_HDR_TYPE_STATIC; // dynamic or static udCompHdr handling +#ifdef OAI_MPLANE + xran_mplane_t *xran_mplane = (xran_mplane_t *)mplane_api; + ru_config->iqWidth = xran_mplane->iq_width; + ru_config->iqWidth_PRACH = xran_mplane->iq_width; +#else ru_config->iqWidth = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH)->uptr; // IQ bit width AssertFatal(ru_config->iqWidth <= 16, "IQ Width cannot be > 16!\n"); - ru_config->compMeth = ru_config->iqWidth < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE; // compression method ru_config->iqWidth_PRACH = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH_PRACH)->uptr; // IQ bit width for PRACH AssertFatal(ru_config->iqWidth_PRACH <= 16, "IQ Width for PRACH cannot be > 16!\n"); +#endif + ru_config->compMeth = ru_config->iqWidth < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE; // compression method ru_config->compMeth_PRACH = ru_config->iqWidth_PRACH < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE; // compression method for PRACH + AssertFatal(fftSize > 0, "FFT size cannot be 0\n"); ru_config->fftSize = fftSize; // FFT Size ru_config->byteOrder = XRAN_NE_BE_BYTE_ORDER; // order of bytes in int16_t in buffer; big or little endian @@ -757,7 +830,7 @@ static bool set_maxmin_pd(const paramdef_t *pd, int num, const char *name, uint1 return true; } -static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat, const openair0_config_t *oai0, struct xran_fh_config *fh_config) +static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_category xran_cat, const openair0_config_t *oai0, struct xran_fh_config *fh_config) { AssertFatal(num_rus == 1 || num_rus == 2, "only support 1 or 2 RUs as of now\n"); AssertFatal(ru_idx < num_rus, "illegal ru_idx %d: must be < %d\n", ru_idx, num_rus); @@ -847,14 +920,14 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat, fh_config->GPS_Alpha = 0; // refers to alpha as defined in section 9.7.2 of ORAN spec. this value should be alpha*(1/1.2288ns), range 0 - 1e7 (ns); offset_nsec = (pConf->GPS_Beta - offset_sec * 100) * 1e7 + pConf->GPS_Alpha fh_config->GPS_Beta = 0; // beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767; offset_sec = pConf->GPS_Beta / 100 - if (!set_fh_prach_config(oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf)) + if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf)) return false; /* SRS only used if XRAN_CATEGORY_B Note: srs_config->eAxC_offset >= prach_config->eAxC_offset + PRACH */ // fh_config->srs_conf = {0}; if (!set_fh_frame_config(oai0, &fh_config->frame_conf)) return false; - if (!set_fh_ru_config(rup, oai0->split7.fftSize, nru, xran_cat, &fh_config->ru_conf)) + if (!set_fh_ru_config(mplane_api, rup, oai0->split7.fftSize, nru, xran_cat, &fh_config->ru_conf)) return false; fh_config->bbdev_enc = NULL; // call back to poll BBDev encoder @@ -889,24 +962,35 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat, return true; } -bool get_xran_config(const openair0_config_t *openair0_cfg, struct xran_fh_init *fh_init, struct xran_fh_config *fh_config) +bool get_xran_config(void *mplane_api, const struct openair0_config *openair0_cfg, struct xran_fh_init *fh_init, struct xran_fh_config *fh_config) { /* This xran integration release is only valid for O-RU CAT A. Therefore, each FH parameter is hardcoded to CAT A. If you are interested in CAT B, please be aware that parameters of fh_init and fh_config structs must be modified accordingly. */ enum xran_category xran_cat = XRAN_CATEGORY_A; - if (!set_fh_init(fh_init, xran_cat)) { + if (!set_fh_init(mplane_api, fh_init, xran_cat)) { printf("could not read FHI 7.2/ORAN config\n"); return false; } +#ifdef OAI_MPLANE + ru_session_list_t *ru_session_list = (ru_session_list_t *)mplane_api; for (int32_t o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { - if (!set_fh_config(o_xu_id, fh_init->xran_ports, xran_cat, openair0_cfg, &fh_config[o_xu_id])) { + xran_mplane_t *xran_mplane = &ru_session_list->ru_session[o_xu_id].xran_mplane; + if (!set_fh_config(xran_mplane, o_xu_id, fh_init->xran_ports, xran_cat, openair0_cfg, &fh_config[o_xu_id])) { + MP_LOG_I("could not read FHI 7.2/RU-specific config\n"); + return false; + } + } +#else + for (int32_t o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { + if (!set_fh_config(NULL, o_xu_id, fh_init->xran_ports, xran_cat, openair0_cfg, &fh_config[o_xu_id])) { printf("could not read FHI 7.2/RU-specific config\n"); return false; } } +#endif return true; } diff --git a/radio/fhi_72/oran-config.h b/radio/fhi_72/oran-config.h index c5a086638f..bbe934e757 100644 --- a/radio/fhi_72/oran-config.h +++ b/radio/fhi_72/oran-config.h @@ -29,7 +29,7 @@ struct xran_fh_init; struct xran_fh_config; struct openair0_config; -bool get_xran_config(const struct openair0_config *openair0_cfg, struct xran_fh_init *fh_init, struct xran_fh_config *fh_config); +bool get_xran_config(void *mplane_api, const struct openair0_config *openair0_cfg, struct xran_fh_init *fh_init, struct xran_fh_config *fh_config); void print_fh_init(const struct xran_fh_init *fh_init); void print_fh_config(const struct xran_fh_config *fh_config); diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index a5e2d5baf7..3a63045817 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -344,8 +344,11 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d } eth->mplane_priv = (void *)&ru_session_list; + + success = get_xran_config((void *)&ru_session_list, openair0_cfg, &fh_init, fh_config); + AssertFatal(success, "[MPLANE] Cannot configure xran with M-plane info.\n"); #else - success = get_xran_config(openair0_cfg, &fh_init, fh_config); + success = get_xran_config(NULL, openair0_cfg, &fh_init, fh_config); AssertFatal(success, "cannot get configuration for xran\n"); #endif From c7dffd416a46450a47b88ad8b6d9119e2bbc77cd Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 18:01:41 +0100 Subject: [PATCH 22/27] Add Benetel550 4x4 reference gNB config file for M-plane --- ...78.273prb.fhi72.4x4-benetel550-mplane.conf | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf new file mode 100644 index 0000000000..6fa4c200dc --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf @@ -0,0 +1,273 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); }); + + nr_cellid = 1; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; + maxMIMO_layers = 2; + pusch_AntennaPorts = 4; + do_CSIRS = 1; + do_SRS = 0; + sib1_tda = 15; + # force_UL256qam_off = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + # n_TimingAdvanceOffset = 0; +# downlinkConfigCommon + #frequencyInfoDL + # center frequency = 3350.01 MHz + # selected SSB frequency = 3349.92 MHz + absoluteFrequencySSB = 623328; + dl_frequencyBand = 78; + # frequency point A = 3300.87 MHz + dl_absoluteFrequencyPointA = 620058; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + #initialDownlinkBWP + #genericParameters + initialDLBWPlocationAndBandwidth = 1099; #38.101-1 Table 5.3.2-1 + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 23; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 1099; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 152; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 0; + preambleReceivedTargetPower = -100; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 8; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 3; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#one (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + +# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB + msg3_DeltaPreamble = 2; + p0_NominalWithGrant = -96; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 0; + p0_nominal = -96; + + ssb_PositionsInBurst_Bitmap = 0x1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 0; + } + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "172.21.6.5"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.51"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.51"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 180; + pucch_TargetSNRx10 = 220; + dl_bler_target_upper = .35; + dl_bler_target_lower = .15; + ul_bler_target_upper = .35; + ul_bler_target_lower = .15; + pusch_FailureThres = 1000; + ul_max_mcs = 28; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 100; + pucch0_dtx_threshold = 80; + pusch_dtx_threshold = 10; + max_ldpc_iterations = 15; + tx_amp_backoff_dB = 12; # needs to match O-RU configuration + L1_rx_thread_core = 8; + L1_tx_thread_core = 10; + phase_compensation = 0; # needs to match O-RU configuration +} +); + +RUs = ( +{ + local_rf = "no"; + nb_tx = 4; + nb_rx = 4; + att_tx = 0; + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + sf_extension = 0; + eNB_instances = [0]; + ru_thread_core = 9; + sl_ahead = 10; + tr_preference = "raw_if4p5"; # important: activate FHI7.2 + do_precoding = 0; # needs to match O-RU configuration +} +); + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level = "info"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + ngap_log_level = "info"; + f1ap_log_level = "info"; +}; + +fhi_72 = { + dpdk_devices = ("0000:c1:11.0", "0000:c1:11.1"); # one VF can be used as well + system_core = 0; + io_core = 1; + worker_cores = (2); + du_key_pair = ("/home/eurecom/.ssh/id_rsa.pub", "/home/eurecom/.ssh/id_rsa"); + du_addr = ("00:11:22:33:44:68","00:11:22:33:44:69"); + vlan_tag = (11, 11); + ru_ip_addr = ("192.168.80.10"); + fh_config = ({ + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + }); +}; From 75d5b31f4ae18b6f77a111766d8f39e26deaa7e8 Mon Sep 17 00:00:00 2001 From: Teodora Date: Sat, 29 Mar 2025 17:28:14 +0100 Subject: [PATCH 23/27] Add Benetel650 8x8 reference DU config file for M-plane --- ...73prb.fhi72.8x8-benetel650_650-mplane.conf | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf new file mode 100644 index 0000000000..28f9baf6f8 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf @@ -0,0 +1,265 @@ +Active_gNBs = ( "gNB-OAI-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_DU_ID = 0xe00; + gNB_name = "gNB-OAI-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); }); + + nr_cellid = 1; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; + pusch_AntennaPorts = 8; + do_CSIRS = 1; + do_SRS = 0; + sib1_tda = 15; + force_UL256qam_off = 1; + maxMIMO_layers = 2; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + # n_TimingAdvanceOffset = 0; +# downlinkConfigCommon + #frequencyInfoDL + # center frequency = 3950.4 MHz + # selected SSB frequency = 3950.4 MHz + absoluteFrequencySSB = 663360; + dl_frequencyBand = 77; + # frequency point A = 3901.26 MHz + dl_absoluteFrequencyPointA = 660084; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + #initialDownlinkBWP + #genericParameters + initialDLBWPlocationAndBandwidth = 1099; #38.101-1 Table 5.3.2-1 + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 77; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 23; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 1099; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 152; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 0; + preambleReceivedTargetPower = -100; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 8; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 3; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#one (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + +# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB + msg3_DeltaPreamble = 2; + p0_NominalWithGrant = -96; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 0; + p0_nominal = -96; + + ssb_PositionsInBurst_Bitmap = 0x1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 5; + nrofDownlinkSlots = 3; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 1; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + } +); + + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "f1"; + local_n_if_name = "enp193s0f0"; + local_n_address = "172.21.16.51"; + remote_n_address = "172.21.6.90"; + local_n_portc = 500; + local_n_portd = 2153; + remote_n_portc = 501; + remote_n_portd = 2153; + pusch_TargetSNRx10 = 120; + pucch_TargetSNRx10 = 200; + dl_bler_target_upper = .35; + dl_bler_target_lower = .15; + ul_bler_target_upper = .35; + ul_bler_target_lower = .15; + pusch_FailureThres = 100; + ul_max_mcs = 28; + min_grant_prb = 1; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 100; + pucch0_dtx_threshold = 80; + pusch_dtx_threshold = 10; + max_ldpc_iterations = 10; + tx_amp_backoff_dB = 12; # needs to match O-RU configuration + L1_rx_thread_core = 8; + L1_tx_thread_core = 10; # relevant after merge of l1_tx_thread + phase_compensation = 0; # needs to match O-RU configuration +} +); + +RUs = ( +{ + local_rf = "no"; + nb_tx = 8; + nb_rx = 8; + att_tx = 0; + att_rx = 0; + bands = [77]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + sf_extension = 0; + eNB_instances = [0]; + ru_thread_core = 9; + sl_ahead = 10; + tr_preference = "raw_if4p5"; # important: activate FHI7.2 + do_precoding = 0; # needs to match O-RU configuration +} +); + +log_config : +{ + global_log_level = "info"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + ngap_log_level = "info"; + f1ap_log_level = "info"; +}; + +fhi_72 = { + dpdk_devices = ("0000:01:01.0", "0000:01:01.1", "0000:01:01.2", "0000:01:01.3"); # two VFs can be used as well + system_core = 0; + io_core = 1; + worker_cores = (2); + du_key_pair = ("/home/eurecom/.ssh/id_rsa.pub", "/home/eurecom/.ssh/id_rsa"); + du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67", "00:11:22:33:44:68", "00:11:22:33:44:69"); + vlan_tag = (5, 5, 6, 6); + ru_ip_addr = ("192.168.80.5", "192.168.80.6"); + fh_config = ( +# RAN650 #1 + { + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + }, +# RAN650 #2 + { + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + }); +}; From bf0a0aa06b19b133be5a0c323535e0c33b2fe5ea Mon Sep 17 00:00:00 2001 From: Teodora Date: Sat, 29 Mar 2025 12:18:50 +0100 Subject: [PATCH 24/27] Clarification on delay profile --- doc/ORAN_FHI7.2_Tutorial.md | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index c28f75a2cf..8da06fe15e 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -942,10 +942,8 @@ Edit the sample OAI gNB configuration file and check following parameters: including the advantages and disadvantages of each mode, refer to [Memory in DPDK](https://www.dpdk.org/memory-in-dpdk-part-2-deep-dive-into-iova/) * `owdm_enable`: used for eCPRI One-Way Delay Measurements; it depends if the RU supports it; if not set to 1 (enabled), default value is 0 (disabled) - * `fh_config`: parameters that need to match RU parameters - * timing parameters (starting with `T`) depend on the RU: `Tadv_cp_dl` is a - single number, the rest pairs of numbers `(x, y)` specifying minimum and - maximum delays + * `fh_config` + * DU delay profile (`T1a` and `Ta4`): pairs of numbers `(x, y)` specifying minimum and maximum delays * `ru_config`: RU-specific configuration: * `iq_width`: Width of DL/UL IQ samples: if 16, no compression, if <16, applies compression @@ -1094,10 +1092,10 @@ fhi_72 = { // mtu fh_config = ( { - // timing, ru_config, prach_config of RU1 + // DU delay profile, ru_config, prach_config of RU1 }, { - // timing, ru_config, prach_config of RU2 + // DU delay profile, ru_config, prach_config of RU2 } ); }; @@ -1121,11 +1119,6 @@ fhi_72 = { fh_config = ( # RAN650 #1 { - Tadv_cp_dl = 125; - T2a_cp_dl = (259, 500); - T2a_cp_ul = (25, 500); - T2a_up = (134, 375); - Ta3 = (152, 160); T1a_cp_dl = (419, 470); T1a_cp_ul = (285, 336); T1a_up = (294, 345); @@ -1137,11 +1130,6 @@ fhi_72 = { }, # RAN650 #2 { - Tadv_cp_dl = 125; - T2a_cp_dl = (259, 500); - T2a_cp_ul = (25, 500); - T2a_up = (134, 375); - Ta3 = (152, 160); T1a_cp_dl = (419, 470); T1a_cp_ul = (285, 336); T1a_up = (294, 345); From a4479a2e65a372452faa44c401c588df5c78c285 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 18:02:27 +0100 Subject: [PATCH 25/27] Add M-plane tutorial --- doc/ORAN_FHI7.2_Tutorial.md | 811 +++++++++++++++++++++++++++++++++++- 1 file changed, 810 insertions(+), 1 deletion(-) diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index 8da06fe15e..da82f69734 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -964,7 +964,7 @@ Layer mapping (eAxC offsets) happens as follows: **Note** - At the moment, OAI is compatible with CAT A O-RU only. Therefore, SRS is not supported. -- XRAN retreives DU MAC address with `rte_eth_macaddr_get()` function. Hence, `fhi_72.du_addr` parameter is not taken into account. +- XRAN retrieves DU MAC address with `rte_eth_macaddr_get()` function. Hence, `fhi_72.du_addr` parameter is not taken into account. # Start and Operation of OAI gNB @@ -1173,6 +1173,815 @@ Note the eight entries after `avg_IO`. You should be able to connect a UE now. + +# OAI Management Plane +We support Configuration Management in OAI gNB, where gNB configures CU-planes, interfaces, TX/RX antennas, and TX/RX carriers for the RU. +The reference specifications: +* `O-RAN.WG4.MP.0-v05.00` +* `O-RAN.WG4.MP-YANGs-v04.00` + +## M-plane prerequisites +Before proceeding, please make sure you have a support for 7.2 interface, as described in [Prerequisites](#prerequisites). + +### DHCP server +The M-plane requires a DHCP server, where the M-plane connection can be established over untagged or tagged VLAN. We tested with untagged (the default VLAN is 1). +Please modify `/etc/dhcp/dhcpd.conf` configuration based on your testbed. + +
+Example DHCP server configuration + +``` +class "vendor-class" { + match option vendor-class-identifier; +} +subclass "vendor-class" "o-ran-ru2/Benetel" { + vendor-option-space VC; +} +option space VC; +option VC.server-address code 129 = array of ip-address; +option VC.server-fqdn code 130 = string; +# Netconf client IP address - DHCP option 43 +option VC.server-address 192.168.80.1; +option VC.server-fqdn "o_du_1.operator.com"; +set vendor-string = option vendor-class-identifier; +# option 143 - DHCPv4 SZTP Redirect Option (RFC8572) +# 2 bytes of URI's length + URI +option sztp code 143 = { unsigned integer 16, string }; +option sztp 15 "https://192.168.80.1"; +# port is optional in URI, e.g. "https://192.168.80.1:222" +#option sztp 20 "https://192.168.80.1:2222"; +subnet 192.168.80.0 netmask 255.255.255.0 { + option routers 192.168.80.1; + option subnet-mask 255.255.255.0; + option domain-name "oai.com"; + option domain-name-servers 172.21.3.100; + host benetel_ru { + # RU MAC address + hardware ethernet ; + # RU IP address + fixed-address ; + } +} +``` +
+ +Please, configure the interface as: +```bash +sudo ip address add 192.168.80.1/24 dev +``` + +### Mandatory packages +* On Fedora (we haven't yet tested RHEL): +```bash +sudo dnf install pcre-devel libssh-devel libxml2-devel libyang2-devel libnetconf2-devel +``` + +* On Ubuntu: +```bash +sudo apt-get install libpcre3-dev libssh-dev libxml2-dev +``` + +On Ubuntu, please note: `sudo apt-get install libyang2-dev libnetconf2-dev` will install unsupported versions (i.e. v2.0.112/v2.0.24 for `libyang2-dev`/`libnetconf2-dev`, but minimum required are v2.1.4/v2.1.25). +Therefore, please compile these libraries from source, as following: + +
+Installing latest v2 libyang2 and libnetconf2 libraries + +``` +rm -rf /tmp/build_mplane_v2 +mkdir /tmp/build_mplane_v2 + +# libyang +cd /tmp/build_mplane_v2 +git clone https://github.com/CESNET/libyang.git +cd libyang +git checkout v2.1.111 +mkdir build && cd build +cmake -DENABLE_TESTS=OFF \ + -DENABLE_VALGRIND_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_INSTALL_RPATH=/usr/local/lib \ + -DPLUGINS_DIR=/usr/local/lib/libyang \ + -DPLUGINS_DIR_EXTENSIONS=/usr/local/lib/libyang/extensions \ + -DPLUGINS_DIR_TYPES=/usr/local/lib/libyang/types \ + -DYANG_MODULE_DIR=/usr/local/share/yang/modules/libyang .. +make -j8 +sudo make install +sudo ldconfig + +#libnetconf +cd /tmp/build_mplane_v2 +git clone https://github.com/CESNET/libnetconf2.git +cd libnetconf2 +git checkout v2.1.37 +mkdir build && cd build +cmake -DENABLE_TESTS=OFF \ + -DENABLE_EXAMPLES=OFF \ + -DENABLE_VALGRIND_TESTS=OFF \ + -DCLIENT_SEARCH_DIR=/usr/local/share/yang/modules \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_INSTALL_RPATH=/usr/local/lib \ + -DLIBYANG_INCLUDE_DIR=/usr/local/include \ + -DLIBYANG_LIBRARY=/usr/local/lib/libyang.so \ + -DLY_VERSION_PATH=/usr/local/include \ + -DYANG_MODULE_DIR=/usr/local/share/yang/modules/libnetconf2 .. +make -j8 +sudo make install +sudo ldconfig + +# to uninstall libraries +# cd /tmp/build_mplane_v2/libyang/build && sudo make uninstall +# cd /tmp/build_mplane_v2/libnetconf2/build && sudo make uninstall +# cd +# rm -rf /tmp/build_mplane_v2 +``` +
+ +If you would like to install these libraries in the custom path, please replace `/usr/local` default path to e.g. `/opt/mplane-v2`. + +## Benetel O-RU +Note: Only v1.2.2 RAN550 and RAN650 have been successfully tested. + +### One time steps +Connect to the RU as user `root`, enable the mplane service, and reboot: +```bash +ssh root@ +systemctl enable mplane +reboot +``` +Once the mplane service is successfully enabled on the RU, two new users are being added in `/etc/passwd`: +```bash +... +oranbenetel:x:1000:1000::/home/oranbenetel:/bin/sh +oranext:x:1001:1001::/home/oranext:/bin/sh +``` +Create `oranbenetel` home directory: +```bash +mkdir /home/oranbenetel && chown oranbenetel:oranbenetel /home/oranbenetel +``` +Connect to the RU as user `oranbenetel`, generate ssh keys, and copy DU public key into RU for NETCONF authentication: +```bash +ssh oranbenetel@ +ssh-keygen +echo "" >> ~/.ssh/authorized_keys +``` + + +## gNB configuration +The reference gNB configuration file for one Benetel RAN550: +[`gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf) +The reference DU configuration file for two Benetel RAN650: +[gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf) + +In order to run gNB/DU with M-plane, we need to modify the `fhi_72` section in the configuration file. +Example for one RU: +```bash +fhi_72 = { + dpdk_devices = ("0000:c3:11.0", "0000:c3:11.1"); # one VF can be used as well + system_core = 0; + io_core = 1; + worker_cores = (2); + du_key_pair = ("/.ssh/id_rsa.pub", "/.ssh/id_rsa"); + du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67"); # only one needed if one VF configured + vlan_tag = (9, 9); # only one needed if one VF configured + ru_ip_addr = ("192.168.80.9"); + fh_config = ({ + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + }); +}; +``` +Example for two RUs: +```bash +fhi_72 = { + dpdk_devices = ("0000:c3:11.0", "0000:c3:11.1", "0000:c3:11.2", "0000:c3:11.3"); # two VFs can be used as well + system_core = 0; + io_core = 1; + worker_cores = (2); + du_key_pair = ("/home/oaicicd/.ssh/id_rsa.pub", "/home/oaicicd/.ssh/id_rsa"); + du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67", "00:11:22:33:44:68", "00:11:22:33:44:69"); # only two needed if two VFs configured + vlan_tag = (9, 9, 11, 11); # only two needed if two VFs configured + ru_ip_addr = ("192.168.80.9", "192.168.80.10"); + fh_config = ( +# RAN550 #1 + { + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + }, +# RAN550 #2 + { + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + }); +}; +``` + +* `fhi_72` : + * `dpdk_devices`: [*] + * `system_core`: [*] + * `io_core`: [*] + * `worker_cores`: [*] + * `file_prefix`: [*] + * `du_key_pair`: ssh public and private keys to authenticate RU with NETCONF + * `du_addr`: DU MAC address(es) to create CU-plane interface(s) in the RU + * `vlan_tag`: VLAN U and C plane tags to create CU-plane interface(s) in the RU + * `ru_ip_addr`: RU IP address to connect to the RU via M-plane + * `dpdk_mem_size`: [*] + * `dpdk_iova_mode`: [*] + * `owdm_enable`: [*] + * `fh_config`: only DU delay profile (`T1a` and `Ta4`) + +[*] see [Configure OAI gNB](#configure-oai-gnb) for more details + +The following parameters are retrieved from the RU and forwarded to the xran: +* `MTU` +* `RU MAC address` +* `IQ compression`: if RU supports multiple, the first value in the list is taken; please note that the same value is used for PxSCH/PRACH +* `PRACH offset`: hardcoded based on the RU vendor (i.e. for Benetel `max(Nrx,Ntx)`) + +## Build and compile gNB +The following cmake options are available: +* `OAI_FHI72` = CUS support +* `OAI_FHI72_MPLANE` = M support + +Compiled libraries: +* `OAI_FHI72` <=> `oran_fhlib_5g` +* `OAI_FHI72` && `OAI_FHI72_MPLANE` <=> `oran_fhlib_5g` (CUS) && `oran_fhlib_5g_mplane` (CUSM) + +### Using build_oai script +```bash +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g +cd ~/openairinterface5g/cmake_targets/ +./build_oai -I # if you never installed OAI, use this command once before the next line +./build_oai --install-optional-packages # for pcre/libpcre3, libssh, and libxml2 library installation +./build_oai --gNB --ninja -t oran_fhlib_5g_mplane --cmake-opt -Dxran_LOCATION=$HOME/phy/fhi_lib/lib +# if libyang2 and libnetconf2 are installed in `/opt/mplane-v2`, please use the following command: +PKG_CONFIG_PATH=/opt/mplane-v2/lib/pkgconfig ./build_oai --gNB --ninja -t oran_fhlib_5g_mplane --cmake-opt -Dxran_LOCATION=$HOME/phy/fhi_lib/lib +``` + +### Using cmake directly +```bash +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g +cd ~/openairinterface5g/ +mkdir build && cd build +cmake .. -GNinja -DOAI_FHI72=ON -DOAI_FHI72_MPLANE=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib +# if libyang2 and libnetconf2 are installed in `/opt/mplane-v2`, please use the following command: +PKG_CONFIG_PATH=/opt/mplane-v2/lib/pkgconfig cmake .. -GNinja -DOAI_FHI72=ON -DOAI_FHI72_MPLANE=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib +ninja nr-softmodem oran_fhlib_5g_mplane params_libconfig +``` + +## Start the gNB +Run the `nr-softmodem` from the build directory: +```bash +cd ~/openairinterface5g/cmake_targets/ran_build/build +sudo ./nr-softmodem -O --thread-pool +``` + +**Warning**: Make sure that the configuration file you add after the `-O` option is adapted to your machine, especially to its isolated cores. + +M-plane sequence diagram: + +```mermaid +sequenceDiagram + participant dhcp as DHCP server + participant du as O-DU + participant ru as O-RU + + dhcp->ru: 1. Transport Layer Initialization + note over dhcp,ru: (a) perform VLAN scan (untagged or tagged VLAN)
(b) DHCP assigns IP address to RU
(c) DHCP sends DU IP address to RU + + du->ru: 2. NETCONF/SSH connect + + du->>ru: 3. DU retrieves RU info + note left of du: + + note over du: Check if RU is PTP synced + + du->>ru: 4. DU subscribes to all RU notifications + note left of du: + + du->>ru: 5. DU updates the supervision timer + note left of du: + + note over du: Store RU MAC, MTU, IQ bitwidth, and PRACH offset info for xran + + note over du: Store all the RU U-plane info - interface name, TX/RX carrier, and TX/RX endpoint names + + du->>ru: 6. DU loads yang models + note left of du: + note right of ru: ietf-netconf-monitoring.yang + + du->>ru: 7. DU performs CU-plane configuration + note left of du: + + note over ru: (1) o-ran-interface.yang - create new interface with VLAN tag, DU and RU MAC addresses
(2)(opt.) o-ran-transceiver.yang - for file upload
(3) o-ran-processing-elements.yang - element with which RU ports should be assigned
(4) o-ran-uplane-conf.yang
#8193;(4a) low-level-tx/rx-endpoints - PxSCH, PRACH
#8193;(4b) tx/rx-array-carriers - center frequency, BW, gain, ACTIVE,...
#8193;(4c) low-level-tx/rx-links - mapping endpoints, carriers and processing element
#8193;(4d)(opt.) if CAT B, SRS configuration
#8193;(4e)(opt.) TDD configuration + + du->>ru: 8. DU checks if CU-plane configuration is valid + note left of du: + + du->>ru: 9. If valid, DU commits the changes + note left of du: + + du->>ru: 10. DU retrieves RU states + note right of ru: ietf-hardware.yang + note left of du: + note over ru: admin-state, power-state, oper-state,
availability-state, usage-state + + ru->>du: 11. RU notifies DU about the configuration change + + note over du: DU configures xran + + du->ru: 12. DU and RU exchange packets +``` + + +
+4x4 MIMO and 100MHz BW with Benetel 550 RU example run + +``` +[HW] [MPLANE] RPC request to RU "192.168.80.9" = with username "oranbenetel" and port ID "830". +[HW] [MPLANE] Successfuly connected to RU "192.168.80.9" with username "oranbenetel" and port ID "830". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = operational datastore. +[HW] [MPLANE] Successfully retrieved operational datastore from RU "192.168.80.9". +[HW] [MPLANE] RU is already PTP synchronized. +[HW] [MPLANE] RPC request to RU "192.168.80.9" = with stream "NETCONF" and filter "(null)". +[HW] [MPLANE] RPC reply = OK. +[HW] [MPLANE] Successfully subscribed to all notifications from RU "192.168.80.9". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = " +65535 +65535 +". +[HW] [MPLANE] Successfully updated supervision timer to (65535+65535)[s] for RU "192.168.80.9". +[HW] [MPLANE] Watchdog timer answer: + 2025-03-30T08:52:31+02:00 + +[HW] [MPLANE] Interface MTU 1500 unreliable/not correctly reported by Benetel O-RU, hardcoding to 9600. +[HW] [MPLANE] IQ bitwidth 16 unreliable/not correctly reported by Benetel O-RU, hardcoding to 9. +[HW] [MPLANE] Storing the following information to forward to xran: + RU MAC address 8c:1f:64:d1:11:c0 + MTU 9600 + IQ bitwidth 9 + PRACH offset 4 + DU port bitmask 61440 + Band sector bitmask 3840 + CC ID bitmask 240 + RU port ID bitmask 15 + DU port ID 0 + Band sector ID 0 + CC ID 0 + RU port ID 0 +[HW] [MPLANE] Successfully retrieved all the U-plane info - interface name, TX/RX carrier names, and TX/RX endpoint names. +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-yang-metadata". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "yang". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-inet-types". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-yang-types". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-yang-schema-mount". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-yang-structure-ext". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-datastores". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "sysrepo". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-netconf-acm". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-factory-default". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "sysrepo-factory-default". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-yang-library". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "sysrepo-monitoring". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "sysrepo-plugind". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-netconf". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-netconf-with-defaults". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-netconf-notifications". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-origin". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-netconf-monitoring". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-netconf-nmda". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "nc-notifications". +[HW] [MPLANE] [LIBYANG] ERROR: Data model "notifications" not found in local searchdirs. (path: (null)). +[HW] [MPLANE] [LIBYANG] ERROR: Loading "notifications" module failed. (path: (null)). +[HW] [MPLANE] [LIBYANG] ERROR: Parsing module "nc-notifications" failed. (path: (null)). +[HW] [MPLANE] Unable to load module "nc-notifications" from RU "192.168.80.9". +[HW] [MPLANE] Unable to load all yang modules from operational datastore for RU "192.168.80.9". Using yang models present in "models" subfolder. +[HW] [MPLANE] Successfully loaded all yang modules for RU "192.168.80.9". +[HW] [MPLANE] The VLAN tags for C and U plane for the RU "192.168.80.9" are the same. Therefore, configuring one common interface and one processing element. +[HW] [MPLANE] RPC request to RU "192.168.80.9" = : + + + INTERFACE_0 + ianaift:l2vlan + true + 8c:1f:64:d1:11:c0 + eth0 + 9 + + + + ETH-INTERFACE + + PLANE_0 + + INTERFACE_0 + + 8c:1f:64:d1:11:c0 + 9 + 00:11:22:33:44:66 + + + + + + + PdschLink0 + PLANE_0 + TxArray0 + LowLevelTxEndpoint0 + + + PdschLink1 + PLANE_0 + TxArray0 + LowLevelTxEndpoint1 + + + PdschLink2 + PLANE_0 + TxArray0 + LowLevelTxEndpoint2 + + + PdschLink3 + PLANE_0 + TxArray0 + LowLevelTxEndpoint3 + + + PuschLink0 + PLANE_0 + RxArray0 + LowLevelRxEndpoint0 + + + PrachLink0 + PLANE_0 + RxArray0 + LowLevelRxPrachEndpoint0 + + + PuschLink1 + PLANE_0 + RxArray0 + LowLevelRxEndpoint1 + + + PrachLink1 + PLANE_0 + RxArray0 + LowLevelRxPrachEndpoint1 + + + PuschLink2 + PLANE_0 + RxArray0 + LowLevelRxEndpoint2 + + + PrachLink2 + PLANE_0 + RxArray0 + LowLevelRxPrachEndpoint2 + + + PuschLink3 + PLANE_0 + RxArray0 + LowLevelRxEndpoint3 + + + PrachLink3 + PLANE_0 + RxArray0 + LowLevelRxPrachEndpoint3 + + + LowLevelTxEndpoint0 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 0 + + + + LowLevelTxEndpoint1 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 1 + + + + LowLevelTxEndpoint2 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 2 + + + + LowLevelTxEndpoint3 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 3 + + + + LowLevelRxEndpoint0 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 0 + + + + LowLevelRxPrachEndpoint0 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 4 + + + + LowLevelRxEndpoint1 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 1 + + + + LowLevelRxPrachEndpoint1 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 5 + + + + LowLevelRxEndpoint2 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 2 + + + + LowLevelRxPrachEndpoint2 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 6 + + + + LowLevelRxEndpoint3 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 3 + + + + LowLevelRxPrachEndpoint3 + + 9 + STATIC + + 0 + 0 + 0 + + 61440 + 3840 + 240 + 15 + 7 + + + + TxArray0 + 663360 + 3950400000 + 100000000 + ACTIVE + 0.0 + 0 + 0 + + + RxArray0 + 663360 + 3950400000 + 100000000 + ACTIVE + 0 + 0 + 0.0 + 0 + + + +[HW] [MPLANE] RPC reply = OK. +[HW] [MPLANE] Successfully edited the candidate datastore for RU "192.168.80.9". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = candidate datastore. +[HW] [MPLANE] RPC reply = OK. +[HW] [MPLANE] Successfully validated candidate datastore for RU "192.168.80.9". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = candidate datastore. +[HW] [MPLANE] RPC reply = OK. +[HW] [MPLANE] Successfully commited CU-planes configuration into running datastore for RU "192.168.80.9". +[HW] [MPLANE] Usage state = "idle" for RU "192.168.80.9". +[HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.049085102+00:00) +{ + "o-ran-uplane-conf:rx-array-carriers-state-change": { + "rx-array-carriers": [ + { + "name": "RxArray0", + "state": "BUSY" + } + ] + } +} + +[HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.058136880+00:00) +{ + "o-ran-uplane-conf:tx-array-carriers-state-change": { + "tx-array-carriers": [ + { + "name": "TxArray0", + "state": "BUSY" + } + ] + } +} + +[HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.078776163+00:00) +{ + "o-ran-uplane-conf:rx-array-carriers-state-change": { + "rx-array-carriers": [ + { + "name": "RxArray0", + "state": "READY" + } + ] + } +} + +[HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.093039138+00:00) +{ + "o-ran-uplane-conf:tx-array-carriers-state-change": { + "tx-array-carriers": [ + { + "name": "TxArray0", + "state": "READY" + } + ] + } +} + +[HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.452751936+00:00) +{ + "ietf-netconf-notifications:netconf-config-change": { + "changed-by": { + "username": "root", + "session-id": 0 + }, + "datastore": "running", + "edit": [ + { + "target": "/ietf-interfaces:interfaces/interface[name='INTERFACE_0']", + "operation": "create" + }, + { + "target": "/ietf-interfaces:interfaces/interface[name='INTERFACE_0']/name", + "operation": "create" + }, +... +} + +[HW] [MPLANE] RU "192.168.80.9" is now ready. +``` +
+ + +Note: If you wish to run the fronthaul without M-plane, no need for recompilation, as the library `oran_fhlib_5g` already exists. +The only mandatory step is to link `oran_fhlib_5g` to `oai_transpro` library. +```bash +cd ~/openairinterface5g/cmake_targets/ran_build/build +rm liboai_transpro.so +ln -s liboran_fhlib_5g.so liboai_transpro.so +sudo ./nr-softmodem -O --thread-pool +``` + + # Contact in case of questions You can ask your question on the [mailing lists](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/MailingList). From 7beb88425fc9b0dc200cb285c5b2649ad81ff258 Mon Sep 17 00:00:00 2001 From: Teodora Date: Mon, 3 Feb 2025 18:18:26 +0100 Subject: [PATCH 26/27] Use [HW] logging instead of [PHY] or [NR_PHY] --- radio/fhi_72/oaioran.c | 24 ++++++++++++------------ radio/fhi_72/oran-init.c | 2 +- radio/fhi_72/oran_isolate.c | 12 ++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 16dd2d85de..cbc530a785 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -90,7 +90,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) rx_sym = callback_tag->symbol & 0xFF; uint32_t ru_id = callback_tag->oXuId; - LOG_D(NR_PHY, + LOG_D(HW, "rx_callback frame %d, subframe %d, slot %d, second %lld, rx_sym %d ru_id %d\n", frame, subframe, @@ -127,7 +127,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) rx_RU[ru_id][slot2] = 1; if (last_frame > 0 && frame > 0 && ((slot2 > 0 && last_frame != frame) || (slot2 == 0 && last_frame != ((1024 + frame - 1) & 1023)))) - LOG_E(PHY, "Jump in frame counter last_frame %d => %d, slot %d\n", last_frame, frame, slot2); + LOG_E(HW, "Jump in frame counter last_frame %d => %d, slot %d\n", last_frame, frame, slot2); for (int i = 0; i < num_ports; i++) { if (rx_RU[i][slot2] == 0) return; @@ -142,16 +142,16 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) info->tti = tti; info->sl = slot2; info->f = frame; - LOG_D(PHY, "Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot); + LOG_D(HW, "Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot); pushNotifiedFIFO(&oran_sync_fifo, req); #else - LOG_D(PHY, "Writing %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); + LOG_D(HW, "Writing %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); oran_sync_info.tti = tti; oran_sync_info.sl = slot2; oran_sync_info.f = frame; #endif } else - LOG_E(PHY, "Cannot Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); + LOG_E(HW, "Cannot Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); last_slot = slot2; last_frame = frame; } // rx_sym == 7 @@ -289,7 +289,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) while ((f = pollNotifiedFIFO(&oran_sync_fifo)) != NULL) { oran_sync_info_t *old_info = NotifiedFifoData(res); oran_sync_info_t *new_info = NotifiedFifoData(f); - LOG_E(PHY, "Detected double sync message %d.%d => %d.%d\n", old_info->f, old_info->sl, new_info->f, new_info->sl); + LOG_E(HW, "Detected double sync message %d.%d => %d.%d\n", old_info->f, old_info->sl, new_info->f, new_info->sl); delNotifiedFIFO_elt(res); res = f; } @@ -305,14 +305,14 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) uint32_t tti_in = oran_sync_info.tti; static int last_slot = -1; - LOG_D(PHY, "oran slot %d, last_slot %d\n", *slot, last_slot); + LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot); int cnt = 0; // while (*slot == last_slot) { while (tti_in == oran_sync_info.tti) { //*slot = oran_sync_info.sl; cnt++; } - LOG_D(PHY, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot); + LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot); last_slot = *slot; #endif // return(0); @@ -380,9 +380,9 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) int16_t payload_len = 0; - LOG_D(PHY, "pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); + LOG_D(HW, "pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { - LOG_D(PHY, + LOG_D(HW, "prbMap[%d] : PRBstart %d nPRBs %d\n", idxElm, pRbMap->prbMap[idxElm].nRBStart, @@ -436,7 +436,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) } // vv_inf if ((*frame & 0x7f) == 0 && *slot == 0 && xran_get_common_counters(gxran_handle, &x_counters[0]) == XRAN_STATUS_SUCCESS) { for (int o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { - LOG_I(NR_PHY, + LOG_I(HW, "[%s%d][rx %7ld pps %7ld kbps %7ld][tx %7ld pps %7ld kbps %7ld][Total Msgs_Rcvd %ld]\n", "o-du ", o_xu_id, @@ -448,7 +448,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) x_counters[o_xu_id].tx_bytes_per_sec * 8 / 1000L, x_counters[o_xu_id].Total_msgs_rcvd); for (int rxant = 0; rxant < ru->nb_rx / fh_init->xran_ports; rxant++) - LOG_I(NR_PHY, + LOG_I(HW, "[%s%d][pusch%d %7ld prach%d %7ld]\n", "o_du", o_xu_id, diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index 97930a172b..fd3fdaa5bf 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -443,7 +443,7 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi pi->prach_tag = tag; pi->pusch_tag = tag; #ifdef E_RELEASE - LOG_W(PHY, "Please be aware that E release support will be removed in the future. Consider switching to F release.\n"); + LOG_W(HW, "Please be aware that E release support will be removed in the future. Consider switching to F release.\n"); oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, &xran_fh_config[o_xu_id]); #elif defined F_RELEASE oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]); diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 3a63045817..0a200a39a0 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -214,11 +214,11 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) RU_proc_t *proc = &ru->proc; int f, sl; - LOG_D(PHY, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]); + LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]); start_meas(&ru->rx_fhaul); int ret = xran_fh_rx_read_slot(&ru_info, &f, &sl); stop_meas(&ru->rx_fhaul); - LOG_D(PHY, "Read %d.%d rxdataF %p,%p\n", f, sl, ru_info.rxdataF[0], ru_info.rxdataF[1]); + LOG_D(HW, "Read %d.%d rxdataF %p,%p\n", f, sl, ru_info.rxdataF[0], ru_info.rxdataF[1]); if (ret != 0) { printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX function \n", f, sl); } @@ -231,7 +231,7 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) if (proc->first_rx == 0) { if (proc->tti_rx != *slot) { - LOG_E(PHY, + LOG_E(HW, "Received Time doesn't correspond to the time we think it is (slot mismatch, received %d.%d, expected %d.%d)\n", proc->frame_rx, proc->tti_rx, @@ -241,7 +241,7 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) } if (proc->frame_rx != *frame) { - LOG_E(PHY, + LOG_E(HW, "Received Time doesn't correspond to the time we think it is (frame mismatch, %d.%d , expected %d.%d)\n", proc->frame_rx, proc->tti_rx, @@ -251,10 +251,10 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) } } else { proc->first_rx = 0; - LOG_I(PHY, "before adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx); + LOG_I(HW, "before adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx); *frame = proc->frame_rx; *slot = proc->tti_rx; - LOG_I(PHY, "After adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx); + LOG_I(HW, "After adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx); } } From 321b1c4ce1ce6c606f259dfac4221013ac46e1be Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Feb 2025 18:21:03 +0100 Subject: [PATCH 27/27] Increase maximum logging line length for in-memory log - Increase the maximum logging line for print done through log_output_memory(). The reason is that we hit this line length when printing some machine generated configuration (XML) through the M-plane. Increase to make more of it visible. - To limit the impact, only increase this locally in function log_output_memory(), and statically assert that it will never be larger than 64 kB. In other places, we use the old limit. - Move the definition MAX_LOG_TOTAL to log.c, because it's only used there. --- common/utils/LOG/log.c | 30 +++++++++++++++++++----------- common/utils/LOG/log.h | 6 ------ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 148da232ae..61003857ab 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -52,6 +52,13 @@ // main log variables +/** @defgroup _max_length Maximum Length of LOG + * @ingroup _macro + * @brief the macros that describe the maximum length of LOG + * @{*/ + +#define MAX_LOG_TOTAL 16384 /*!< \brief the maximum length of a log */ + // Fixme: a better place to be shure it is called void read_cpu_hardware (void) __attribute__ ((constructor)); #if !defined(__arm__) && !defined(__aarch64__) @@ -877,31 +884,32 @@ static void log_output_memory(log_component_t *c, const char *file, const char * * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is * big enough so that the buffer is never full. */ - char log_buffer[MAX_LOG_TOTAL]; + static_assert(4 * MAX_LOG_TOTAL <= 65536, "log buffer limited to 64kB, please reduce MAX_LOG_TOTAL\n"); + char log_buffer[4 * MAX_LOG_TOTAL]; // make sure that for log trace the extra info is only printed once, reset when the level changes if (level < OAILOG_TRACE) { - int n = log_header(c, log_buffer+len, MAX_LOG_TOTAL, file, func, line, level); + int n = log_header(c, log_buffer+len, sizeof(log_buffer), file, func, line, level); if (n > 0) { len += n; - if (len > MAX_LOG_TOTAL) { - len = MAX_LOG_TOTAL; + if (len > sizeof(log_buffer)) { + len = sizeof(log_buffer); } } } - int n = vsnprintf(log_buffer+len, MAX_LOG_TOTAL-len, format, args); + int n = vsnprintf(log_buffer+len, sizeof(log_buffer)-len, format, args); if (n > 0) { len += n; - if (len > MAX_LOG_TOTAL) { - len = MAX_LOG_TOTAL; + if (len > sizeof(log_buffer)) { + len = sizeof(log_buffer); } } if (!((g_log->flag) & FLAG_NOCOLOR)) { - int n = snprintf(log_buffer+len, MAX_LOG_TOTAL-len, "%s", log_level_highlight_end[level]); + int n = snprintf(log_buffer+len, sizeof(log_buffer)-len, "%s", log_level_highlight_end[level]); if (n > 0) { len += n; - if (len > MAX_LOG_TOTAL) { - len = MAX_LOG_TOTAL; + if (len > sizeof(log_buffer)) { + len = sizeof(log_buffer); } } } @@ -941,7 +949,7 @@ static void log_output_memory(log_component_t *c, const char *file, const char * } } }else{ - AssertFatal(len >= 0 && len <= MAX_LOG_TOTAL, "Bad len %d\n", len); + AssertFatal(len >= 0 && len <= sizeof(log_buffer), "Bad len %d\n", len); if (write(fileno(c->stream), log_buffer, len)) {}; } } diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index d153a4aeaf..7b9b570a06 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -65,12 +65,6 @@ extern "C" { #endif -/** @defgroup _max_length Maximum Length of LOG - * @ingroup _macro - * @brief the macros that describe the maximum length of LOG - * @{*/ - -#define MAX_LOG_TOTAL 16384 /*!< \brief the maximum length of a log */ /** @}*/ /** @defgroup _log_level Message levels defined by LOG