From 0b684732eef24ce48cecc4dd8d02e69c5257cbdc Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Fri, 5 Jul 2024 18:10:40 +0200 Subject: [PATCH 1/2] YAML as a drop-in replacement for libconfig This commit introduces a substitute module library for setting up softmodems using YAML instead of libconfig. The softmodems should work the same with both types of files. Extra care was put to make sure the behavior of both modules is the same. Example yaml config files were added for the UE and gNB --- ci-scripts/conf_files/nrue.uicc.yaml | 28 ++ cmake_targets/tools/build_helper | 8 +- common/CMakeLists.txt | 1 + common/config/config_load_configmodule.c | 8 +- common/config/yaml/CMakeLists.txt | 26 ++ common/config/yaml/config_yaml.cpp | 327 +++++++++++++++ common/config/yaml/tests/CMakeLists.txt | 11 + common/config/yaml/tests/test1.yaml | 4 + common/config/yaml/tests/test_int_array.yaml | 6 + common/config/yaml/tests/test_list.yaml | 13 + .../yaml/tests/test_list_of_mappings.yml | 14 + common/config/yaml/tests/test_recursion.yaml | 8 + common/config/yaml/tests/test_string.yaml | 6 + common/config/yaml/tests/test_yaml_config.cpp | 373 ++++++++++++++++++ .../gnb.sa.band78.fr1.106PRB.usrpb210.yaml | 221 +++++++++++ 15 files changed, 1049 insertions(+), 5 deletions(-) create mode 100644 ci-scripts/conf_files/nrue.uicc.yaml create mode 100644 common/config/yaml/CMakeLists.txt create mode 100644 common/config/yaml/config_yaml.cpp create mode 100644 common/config/yaml/tests/CMakeLists.txt create mode 100644 common/config/yaml/tests/test1.yaml create mode 100644 common/config/yaml/tests/test_int_array.yaml create mode 100644 common/config/yaml/tests/test_list.yaml create mode 100644 common/config/yaml/tests/test_list_of_mappings.yml create mode 100644 common/config/yaml/tests/test_recursion.yaml create mode 100644 common/config/yaml/tests/test_string.yaml create mode 100644 common/config/yaml/tests/test_yaml_config.cpp create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml diff --git a/ci-scripts/conf_files/nrue.uicc.yaml b/ci-scripts/conf_files/nrue.uicc.yaml new file mode 100644 index 0000000000..518315c7ff --- /dev/null +++ b/ci-scripts/conf_files/nrue.uicc.yaml @@ -0,0 +1,28 @@ +uicc0: + imsi: 208990100001100 + key: fec86ba6eb707ed08905757b1bb44b8f + opc: C42449363BBAD02B66D16BC975D77CC1 + dnn: oai + nssai_sst: 1 + +#/* configuration for channel modelisation */ +#/* To be included in main config file when */ +#/* channel modelisation is used (rfsimulator with chanmod options enabled) */ +channelmod: + max_chan: 10; + modellist: modellist_rfsimu_1 + modellist_rfsimu_1: + - model_name: rfsimu_channel_enB0 + type: AWGN + ploss_dB: 20 + noise_power_dB: -4 + forgetfact: 0 + offset: 0 + ds_tdl: 0 + - model_name: rfsimu_channel_ue0 + type: AWGN + ploss_dB: 20 + nose_power_dB: -2 + forgetfact: 0 + offset: 0 + ds_tdl: 0 diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 30cb1f0b00..23558bfe56 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -589,8 +589,9 @@ check_install_oai_software() { libtool \ patch \ openssl \ - zlib1g-dev \ - xxd + zlib1g-dev \ + xxd \ + libyaml-cpp-dev elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then @@ -625,7 +626,8 @@ check_install_oai_software() { blas \ blas-devel \ vim-common \ - zlib-devel + zlib-devel \ + yaml-cpp-devel fi install_asn1c_from_source $1 diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 6c2d123397..14c4ac582a 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(utils) +add_subdirectory(config/yaml) configure_file(oai_version.h.in oai_version.h @ONLY) diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 411e737976..71cab2a33a 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -293,8 +293,12 @@ configmodule_interface_t *load_configmodule(int argc, } else if ( i == 1 ) { /* -O argument doesn't contain ":" separator, assume -O option, default cfgmode to libconfig with one parameter, the path to the configuration file cfgmode must not be NULL */ - modeparams=cfgmode; - cfgmode=strdup(CONFIG_LIBCONFIGFILE); + modeparams = cfgmode; + if (strstr(modeparams, ".yaml") != NULL || strstr(modeparams, ".yml") != NULL) { + cfgmode = strdup("yaml"); + } else { + cfgmode = strdup(CONFIG_LIBCONFIGFILE); + } } static configmodule_interface_t *cfgptr; if (cfgptr) diff --git a/common/config/yaml/CMakeLists.txt b/common/config/yaml/CMakeLists.txt new file mode 100644 index 0000000000..67d90a0099 --- /dev/null +++ b/common/config/yaml/CMakeLists.txt @@ -0,0 +1,26 @@ +find_package(yaml-cpp REQUIRED) + +# include(FetchContent) + +# FetchContent_Declare( +# yaml-cpp +# GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git +# GIT_TAG 0.8.0 +# ) +# FetchContent_GetProperties(yaml-cpp) + +# if(NOT yaml-cpp_POPULATED) +# message(STATUS "Fetching yaml-cpp...") +# FetchContent_Populate(yaml-cpp) +# add_subdirectory(${yaml-cpp_SOURCE_DIR} ${yaml-cpp_BINARY_DIR}) +# endif() + +add_library(params_yaml_static config_yaml.cpp) +target_link_libraries(params_yaml_static PUBLIC UTIL yaml-cpp) +if (ENABLE_TESTS) + add_subdirectory(tests) +endif() + +add_library(params_yaml MODULE config_yaml.cpp) +target_link_libraries(params_yaml PUBLIC UTIL yaml-cpp) +set_target_properties(params_yaml PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/common/config/yaml/config_yaml.cpp b/common/config/yaml/config_yaml.cpp new file mode 100644 index 0000000000..c2af51e2db --- /dev/null +++ b/common/config/yaml/config_yaml.cpp @@ -0,0 +1,327 @@ +/* + * 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 "yaml-cpp/yaml.h" +extern "C" { +#include "common/config/config_load_configmodule.h" +#include "common/config/config_userapi.h" +void *config_allocate_new(configmodule_interface_t *cfg, int sz, bool autoFree); +void config_check_valptr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int elt_sz, int nb_elt); +} +#include +#include +#include +#include +#include + +namespace config_yaml { +class YamlConfig { + public: + YAML::Node config; + YamlConfig(std::string filename) + { + config = YAML::LoadFile(filename); + } +}; + +void SetDefault(configmodule_interface_t *cfg, paramdef_t *param) +{ + switch (param->type) { + case TYPE_INT: + *param->iptr = param->defintval; + break; + case TYPE_UINT: + *param->uptr = param->defuintval; + break; + case TYPE_STRING: + if (param->defstrval != nullptr) { + if (param->numelt == 0) { + config_check_valptr(cfg, param, 1, strlen(param->defstrval) + 1); + } + sprintf(*param->strptr, "%s", param->defstrval); + } + break; + case TYPE_INT8: + *param->i8ptr = param->defintval; + break; + case TYPE_UINT8: + *param->i8ptr = param->defuintval; + break; + case TYPE_INT16: + *param->i16ptr = param->defintval; + break; + case TYPE_UINT16: + *param->u16ptr = param->defuintval; + break; + case TYPE_INT64: + *param->i64ptr = param->defint64val; + break; + case TYPE_UINT64: + *param->u64ptr = param->defint64val; + break; + case TYPE_DOUBLE: + *param->dblptr = param->defdblval; + break; + case TYPE_MASK: + *param->uptr = param->defuintval; + break; + case TYPE_STRINGLIST: + if (param->defstrlistval != nullptr) { + param->strlistptr = param->defstrlistval; + } + break; + case TYPE_INTARRAY: + if (param->defintarrayval) { + param->iptr = param->defintarrayval; + } + break; + case TYPE_UINTARRAY: + if (param->defintarrayval) { + param->uptr = (uint32_t *)param->defintarrayval; + } + break; + default: + AssertFatal(false, "Unhandled type %d", param->type); + } + param->paramflags |= PARAMFLAG_PARAMSETDEF; +} + +void SetNonDefault(configmodule_interface_t *cfg, const YAML::Node &node, paramdef_t *param) +{ + auto optname = std::string(param->optname); + switch (param->type) { + case TYPE_INT: + *param->iptr = node[optname].as(); + break; + case TYPE_UINT: + *param->uptr = node[optname].as(); + break; + case TYPE_STRING: { + std::string setting = node[optname].as(); + config_check_valptr(cfg, param, 1, setting.length() + 1); + sprintf(*param->strptr, "%s", setting.c_str()); + break; + } + case TYPE_UINT8: + *param->i8ptr = node[optname].as(); + break; + case TYPE_INT16: + *param->i16ptr = node[optname].as(); + break; + case TYPE_UINT16: + *param->u16ptr = node[optname].as(); + break; + case TYPE_INT64: + *param->i64ptr = node[optname].as(); + break; + case TYPE_UINT64: + *param->u64ptr = node[optname].as(); + break; + case TYPE_DOUBLE: + *param->dblptr = node[optname].as(); + break; + case TYPE_MASK: + *param->uptr = node[optname].as(); + break; + case TYPE_STRINGLIST: { + if (node[optname].IsSequence()) { + config_check_valptr(cfg, param, sizeof(char *), node[optname].size()); + int i = 0; + for (const auto &elem : node[optname]) { + sprintf(param->strlistptr[i], "%s", elem.as().c_str()); + i++; + } + param->numelt = i; + } else { + param->numelt = 0; + } + break; + } + case TYPE_INTARRAY: { + if (node[optname].IsSequence() && node[optname].size() > 0) { + param->numelt = node[optname].size(); + param->iptr = + (int32_t *)config_allocate_new(cfg, param->numelt * sizeof(*param->iptr), !(param->paramflags & PARAMFLAG_NOFREE)); + + for (int i = 0; i < param->numelt; i++) { + param->iptr[i] = node[optname][i].as(); + } + } else { + param->numelt = 0; + } + break; + } + case TYPE_UINTARRAY: { + if (node[optname].IsSequence() && node[optname].size() > 0) { + param->numelt = node[optname].size(); + param->uptr = + (uint32_t *)config_allocate_new(cfg, param->numelt * sizeof(*param->uptr), !(param->paramflags & PARAMFLAG_NOFREE)); + + for (int i = 0; i < param->numelt; i++) { + param->uptr[i] = node[optname][i].as(); + } + } else { + param->numelt = 0; + } + break; + } + default: + AssertFatal(false, "Unhandled type %d", param->type); + } + param->paramflags |= PARAMFLAG_PARAMSET; +} + +void GetParams(configmodule_interface_t *cfg, const YAML::Node &node, paramdef_t *params, int num_params) +{ + for (auto i = 0; i < num_params; i++) { + if (node && node[std::string(params[i].optname)]) { + SetNonDefault(cfg, node, ¶ms[i]); + } else { + SetDefault(cfg, ¶ms[i]); + } + } +} + +static YamlConfig *config; +static YAML::Node invalid_node; +} // namespace config_yaml + +extern "C" int config_yaml_init(configmodule_interface_t *cfg) +{ + char **cfgP = cfg->cfgP; + cfg->numptrs = 0; + pthread_mutex_init(&cfg->memBlocks_mutex, NULL); + memset(cfg->oneBlock, 0, sizeof(cfg->oneBlock)); + + config_yaml::config = new config_yaml::YamlConfig(std::string(cfgP[0])); + return 0; +} + +extern "C" void config_yaml_end(configmodule_interface_t *cfg) +{ + delete config_yaml::config; +} + +YAML::Node find_node(const std::string &prefix, YAML::Node node) +{ + // Iterate through each key in the prefix + std::stringstream ss(prefix); + std::string key; + YAML::Node current = node; + + while (std::getline(ss, key, '.')) { + if (key.at(0) == '[' && key.back() == ']') { + // The key is an index to a sequence + if (!current.IsSequence()) { + throw std::invalid_argument("Incorrect yaml file structure"); + } + int index = std::stoi(key.substr(1, key.size() - 2)); + current = current[index]; + continue; + } + if (!current.IsMap()) { + throw std::invalid_argument("Incorrect yaml file structure"); + } + if (!current[key]) { + return config_yaml::invalid_node; + } + current = current[key]; + } + return current; +} + +extern "C" int config_yaml_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix) +{ + std::string p; + if (prefix != nullptr) { + p = std::string(prefix); + } + auto node = find_node(p, YAML::Clone(config_yaml::config->config)); + if (node == config_yaml::invalid_node) { + return -1; + } + for (auto i = 0; i < numoptions; i++) { + if (cfgoptions[i].type != TYPE_STRING && cfgoptions[i].type != TYPE_INTARRAY && cfgoptions[i].type != TYPE_UINTARRAY + && cfgoptions[i].voidptr == nullptr) { + config_check_valptr(cfg, &cfgoptions[i], sizeof(void *), 1); + } + } + config_yaml::GetParams(cfg, node, cfgoptions, numoptions); + return 0; +} + +extern "C" int config_yaml_getlist(configmodule_interface_t *cfg, + paramlist_def_t *ParamList, + paramdef_t *params, + int numparams, + char *prefix) +{ + char path[512]; + if (prefix != nullptr) { + sprintf(path, "%s.%s", prefix, ParamList->listname); + } else { + sprintf(path, "%s", ParamList->listname); + } + ParamList->numelt = 0; + auto node = find_node(path, YAML::Clone(config_yaml::config->config)); + if (node == config_yaml::invalid_node) { + return -1; + } + + if (!node.IsSequence()) { + return -1; + } + ParamList->numelt = node.size(); + + if (ParamList->numelt > 0 && params != NULL) { + ParamList->paramarray = static_cast(config_allocate_new(cfg, ParamList->numelt * sizeof(paramdef_t *), true)); + + for (int i = 0; i < ParamList->numelt; i++) { + ParamList->paramarray[i] = static_cast(config_allocate_new(cfg, numparams * sizeof(paramdef_t), true)); + memcpy(ParamList->paramarray[i], params, sizeof(paramdef_t) * numparams); + + for (int j = 0; j < numparams; j++) { + ParamList->paramarray[i][j].strptr = NULL; + if (ParamList->paramarray[i][j].type != TYPE_STRING) { + config_check_valptr(cfg, &ParamList->paramarray[i][j], sizeof(void *), 1); + } + } + + config_yaml::GetParams(cfg, node[i], ParamList->paramarray[i], numparams); + } + } + + return ParamList->numelt; +} + +extern "C" void config_yaml_write_parsedcfg(configmodule_interface_t *cfg) +{ + (void)cfg; +} + +extern "C" int config_yaml_set(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix) +{ + (void)cfg; + (void)cfgoptions; + (void)numoptions; + (void)prefix; + return 0; +} diff --git a/common/config/yaml/tests/CMakeLists.txt b/common/config/yaml/tests/CMakeLists.txt new file mode 100644 index 0000000000..b28bb8d47f --- /dev/null +++ b/common/config/yaml/tests/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(test_yaml_config test_yaml_config.cpp) +target_link_libraries(test_yaml_config PRIVATE params_yaml_static GTest::gtest) +add_dependencies(tests test_yaml_config) +add_test(NAME test_yaml_config + COMMAND ./test_yaml_config) +configure_file(test1.yaml test1.yaml COPYONLY) +configure_file(test_recursion.yaml test_recursion.yaml COPYONLY) +configure_file(test_list.yaml test_list.yaml COPYONLY) +configure_file(test_string.yaml test_string.yaml COPYONLY) +configure_file(test_list_of_mappings.yml test_list_of_mappings.yml COPYONLY) +configure_file(test_int_array.yaml test_int_array.yaml COPYONLY) diff --git a/common/config/yaml/tests/test1.yaml b/common/config/yaml/tests/test1.yaml new file mode 100644 index 0000000000..7b064b0d38 --- /dev/null +++ b/common/config/yaml/tests/test1.yaml @@ -0,0 +1,4 @@ +test: + value1: 1 + value2: 2 + value3: 3 diff --git a/common/config/yaml/tests/test_int_array.yaml b/common/config/yaml/tests/test_int_array.yaml new file mode 100644 index 0000000000..498db5d31c --- /dev/null +++ b/common/config/yaml/tests/test_int_array.yaml @@ -0,0 +1,6 @@ +test: + array: [1, 2, 3, 4] + array2: + - 1 + - 2 + - 3 diff --git a/common/config/yaml/tests/test_list.yaml b/common/config/yaml/tests/test_list.yaml new file mode 100644 index 0000000000..a7d4b38a59 --- /dev/null +++ b/common/config/yaml/tests/test_list.yaml @@ -0,0 +1,13 @@ +test: + - + value1: 1 + value2: 2 + value3: 3 + - + value1: 4 + value2: 5 + value3: 6 + - + value1: 7 + value2: 8 + value3: 9 diff --git a/common/config/yaml/tests/test_list_of_mappings.yml b/common/config/yaml/tests/test_list_of_mappings.yml new file mode 100644 index 0000000000..e8bc8c9f00 --- /dev/null +++ b/common/config/yaml/tests/test_list_of_mappings.yml @@ -0,0 +1,14 @@ +test: + list: + - value1: 1 + value2: 3 + list: + - value1 + - value2 + - value3 + - value: 2 + value2: 6 + list: + - value4 + - value5 + - value6 diff --git a/common/config/yaml/tests/test_recursion.yaml b/common/config/yaml/tests/test_recursion.yaml new file mode 100644 index 0000000000..0cf2c723ce --- /dev/null +++ b/common/config/yaml/tests/test_recursion.yaml @@ -0,0 +1,8 @@ +test: + test1: + test2: + test3: + test4: + value1: 1 + value2: 2 + value3: 3 diff --git a/common/config/yaml/tests/test_string.yaml b/common/config/yaml/tests/test_string.yaml new file mode 100644 index 0000000000..e093ea3880 --- /dev/null +++ b/common/config/yaml/tests/test_string.yaml @@ -0,0 +1,6 @@ +test: + stringvalue: testvalue + stringlist: + - testvalue1 + - testvalue2 + - testvalue3 diff --git a/common/config/yaml/tests/test_yaml_config.cpp b/common/config/yaml/tests/test_yaml_config.cpp new file mode 100644 index 0000000000..921a455dfd --- /dev/null +++ b/common/config/yaml/tests/test_yaml_config.cpp @@ -0,0 +1,373 @@ +/* + * 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 "gtest/gtest.h" +extern "C" { +#include "common/config/config_paramdesc.h" +// TODO: Should use minimal_lib for this but for some reason it doesn't link properly +uint64_t get_softmodem_optmask(void) +{ + return 0; +} +configmodule_interface_t *uniqCfg; +void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) +{ + if (assert) { + abort(); + } else { + exit(EXIT_SUCCESS); + } +} + +#include "common/utils/LOG/log.h" +#include "common/config/config_load_configmodule.h" +#include "common/config/config_userapi.h" +} +#include +#include +#include +#include +#include + +extern "C" { +int config_yaml_init(configmodule_interface_t *cfg); +void config_yaml_end(configmodule_interface_t *cfg); +int config_yaml_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix); +int config_yaml_getlist(configmodule_interface_t *cfg, paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix); +void config_yaml_write_parsedcfg(configmodule_interface_t *cfg); +int config_yaml_set(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix); +} + +TEST(yaml_config, yaml_basic) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test1.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + + +TEST(yaml_config, yaml_get_existing_values) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test1.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + // Testing paremters present in the test node + paramdef_t p = {0}; + for (auto i = 1; i <= 3; i++) { + sprintf(p.optname, "%s%d", "value", i); + uint16_t value; + p.type = TYPE_UINT16; + p.u16ptr = &value; + char prefix[] = "test"; + config_yaml_get(cfg, &p, 1, prefix); + EXPECT_EQ(value, i); + } + + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, yaml_get_non_existing_values) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test1.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + // Testing paremters present in the test node + paramdef_t p = {0}; + for (auto i = 4; i <= 5; i++) { + sprintf(p.optname, "%s%d", "value", i); + uint16_t value; + p.type = TYPE_UINT16; + p.u16ptr = &value; + p.defuintval = i; + char prefix[] = "test"; + config_yaml_get(cfg, &p, 1, prefix); + EXPECT_EQ(value, i); + } + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_high_recusion) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_recursion.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + // Testing paremters present in the test node + paramdef_t p = {0}; + for (auto i = 1; i <= 3; i++) { + sprintf(p.optname, "%s%d", "value", i); + uint16_t value; + p.type = TYPE_UINT16; + p.u16ptr = &value; + char prefix[] = "test.test1.test2.test3.test4"; + EXPECT_EQ(config_yaml_get(cfg, &p, 1, prefix), 0); + EXPECT_EQ(value, i); + } + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_list) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_list.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramlist_def_t param_list = {0}; + sprintf(param_list.listname, "%s", "test"); + paramdef_t params[3] = {0}; + uint16_t value[3]; + for (auto i = 0; i < 3; i++) { + sprintf(params[i].optname, "%s%d", "value", i+1); + params[i].type = TYPE_UINT16; + params[i].u16ptr = &value[i]; + } + + + config_yaml_getlist(cfg, ¶m_list, params, 3, nullptr); + + for (auto i = 0; i < 3; i++) { + for (auto j = 0; j < 3; j++) { + EXPECT_EQ(*param_list.paramarray[i][j].u16ptr, i * 3 + j + 1); + } + } + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_string_auto_alloc) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_string.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramdef_t param = {0}; + param.type = TYPE_STRING; + param.strptr = nullptr; + sprintf(param.optname, "%s", "stringvalue"); + param.defstrval = nullptr; + + // Test automatic allocation of strings + char prefix[] = "test"; + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_NE(param.strptr, nullptr); + EXPECT_EQ(strcmp(*param.strptr, "testvalue"), 0); + EXPECT_EQ(cfg->numptrs, 2); + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_string_no_realloc) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_string.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramdef_t param = {0}; + param.type = TYPE_STRING; + param.strptr = nullptr; + sprintf(param.optname, "%s", "stringvalue"); + param.defstrval = nullptr; + + // check that if we at least have a non-null pointer to pointer, only one buffer is allocated + char prefix[] = "test"; + char* non_null_pointer_to_pointer = nullptr; + param.strptr = &non_null_pointer_to_pointer; + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_EQ(param.strptr, &non_null_pointer_to_pointer); + EXPECT_EQ(strcmp(*param.strptr, "testvalue"), 0); + EXPECT_EQ(cfg->numptrs, 1); + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_string_pointer_available) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_string.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramdef_t param = {0}; + param.type = TYPE_STRING; + param.strptr = nullptr; + sprintf(param.optname, "%s", "stringvalue"); + param.defstrval = nullptr; + + // Test that if a strptr is provided, config module doesnt reallocate it + char prefix[] = "test"; + char *container = (char *)malloc(sizeof(char) * 30); + param.strptr = &container; + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_EQ(param.strptr, &container); + EXPECT_EQ(strcmp(*param.strptr, "testvalue"), 0); + EXPECT_EQ(cfg->numptrs, 0); + free(container); + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_string_default_value) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_string.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramdef_t param = {0}; + param.type = TYPE_STRING; + param.strptr = nullptr; + sprintf(param.optname, "%s", "stringvalue"); + param.defstrval = nullptr; + + // Test that if defstrval is not null and value is missing in yaml defstrval is set + char prefix[] = "test"; + char default_value[] = "default"; + param.defstrval = default_value; + param.strptr = nullptr; + sprintf(param.optname, "%s", "stringvalue_missing"); + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_NE(param.strptr, nullptr); + EXPECT_EQ(strcmp(*param.strptr, "default"), 0); + EXPECT_EQ(cfg->numptrs, 2) << " 2 pointers required, 1 for the string, one for the pointer-to string"; + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_stringlist) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_string.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramdef_t param = {0}; + param.type = TYPE_STRINGLIST; + param.strptr = nullptr; + sprintf(param.optname, "%s", "stringlist"); + param.defstrval = nullptr; + + // Test automatic allocation of string lists + char prefix[] = "test"; + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_NE(param.strptr, nullptr); + for (auto i = 0; i < param.numelt; i++) { + std::cout << (param.strlistptr)[i] << std::endl; + } + // config_check_valptr allocates maximum list size regardless of the number of elements in list + EXPECT_EQ(cfg->numptrs, MAX_LIST_SIZE + 1); + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_list_of_mappings) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_list_of_mappings.yml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramdef_t param = {0}; + param.type = TYPE_STRINGLIST; + param.strlistptr = nullptr; + sprintf(param.optname, "%s", "list"); + param.defstrval = nullptr; + + // Test automatic allocation of string lists + char prefix1[] = "test.list.[0]"; + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix1), 0); + EXPECT_NE(param.strptr, nullptr); + EXPECT_STREQ("value1", param.strlistptr[0]); + EXPECT_STREQ("value2", param.strlistptr[1]); + EXPECT_STREQ("value3", param.strlistptr[2]); + + char prefix2[] = "test.list.[1]"; + param.strlistptr = nullptr; + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix2), 0); + EXPECT_NE(param.strptr, nullptr); + EXPECT_STREQ("value4", param.strlistptr[0]); + EXPECT_STREQ("value5", param.strlistptr[1]); + EXPECT_STREQ("value6", param.strlistptr[2]); + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +TEST(yaml_config, test_int_array) { + configmodule_interface_t *cfg = static_cast(calloc(1, sizeof(*cfg))); + cfg->cfgP[0] = strdup("test_int_array.yaml"); + EXPECT_EQ(config_yaml_init(cfg), 0); + + paramdef_t param = {0}; + param.type = TYPE_INTARRAY; + param.iptr = nullptr; + sprintf(param.optname, "%s", "array"); + param.defintarrayval = nullptr; + + // Test automatic allocation of int arrays + char prefix[] = "test"; + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_NE(param.iptr, nullptr); + ASSERT_EQ(param.numelt, 4); + EXPECT_EQ(1, param.iptr[0]); + EXPECT_EQ(2, param.iptr[1]); + EXPECT_EQ(3, param.iptr[2]); + EXPECT_EQ(4, param.iptr[3]); + + param.uptr = nullptr; + param.numelt = 0; + sprintf(param.optname, "%s", "array2"); + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_NE(param.uptr, nullptr); + ASSERT_EQ(param.numelt, 3); + EXPECT_EQ(1U, param.uptr[0]); + EXPECT_EQ(2U, param.uptr[1]); + EXPECT_EQ(3U, param.uptr[2]); + + param.uptr = nullptr; + param.numelt = 0; + sprintf(param.optname, "%s", "non-existent-array"); + EXPECT_EQ(config_yaml_get(cfg, ¶m, 1, prefix), 0); + EXPECT_EQ(param.uptr, nullptr); + ASSERT_EQ(param.numelt, 0); + + config_yaml_end(cfg); + free(cfg->cfgP[0]); + end_configmodule(cfg); +} + +int main(int argc, char** argv) +{ + logInit(); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml new file mode 100644 index 0000000000..a215c71304 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml @@ -0,0 +1,221 @@ +Active_gNBs: + - gNB-OAI +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: 001 + mnc: 01 + mnc_length: 2 + snssaiList: + - + sst: 1 + nr_cellid: 12345678 + # Physical parameters: + do_CSIRS: 1 + do_SRS: 1 + servingCellConfigCommon: + #spCellConfigCommon + - physCellId: 0 + # downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB: 641280 + dl_frequencyBand: 78 + # this is 3600 MHz + dl_absoluteFrequencyPointA: 640008 + #scs-SpecificCarrierList + dl_offstToCarrier: 0 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing: 1 + dl_carrierBandwidth: 106 + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth: 28875 # 6366 12925 12956 28875 12952 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing: 1 + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero: 12 + 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: 106 + pMax: 20 + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth: 28875 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing: 1 + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex: 98 + #prach_msg1_FDM + #0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM: 0 + prach_msg1_FrequencyStart: 0 + zeroCorrelationZoneConfig: 13 + preambleReceivedTargetPower: -96 + #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax: 6 + #powerRampingStep + # 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep: 1 + #ra_ReponseWindow + #1,2,4,8,10,20,40,80 + ra_ResponseWindow: 4 + #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 + #oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB: 14 + #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 + msg3_DeltaPreamble: 1 + p0_NominalWithGrant: -90 + # pucch-ConfigCommon setup : + # pucchGroupHopping + # 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping: 0 + hoppingId: 40 + p0_nominal: -90 + # ssb_PositionsInBurs_BitmapPR + # 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR: 2 + ssb_PositionsInBurst_Bitmap: 1 + + # 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: -25 + SCTP: + SCTP_INSTREAMS: 2 + SCTP_OUTSTREAMS: 2 + + + # AMF parameters: + amf_ip_address: + ipv4: 192.168.70.132 + + + NETWORK_INTERFACES: + GNB_IPV4_ADDRESS_FOR_NG_AMF: 192.168.70.129 + GNB_IPV4_ADDRESS_FOR_NGU: 192.168.70.129 + GNB_PORT_FOR_S1U: 2152 # Spec 2152 + +MACRLCs: + - + num_cc: 1 + tr_s_preference: local_L1 + tr_n_preference: local_RRC + pusch_TargetSNRx10: 150 + pucch_TargetSNRx10: 200 + +L1s: + - + num_cc: 1 + tr_n_preference: local_mac + prach_dtx_threshold: 120 + pucch0_dtx_threshold: 100 + ofdm_offset_divisor: 8 #set this to UINT_MAX for offset 0 + +RUs: + - + local_rf: yes + nb_tx: 1 + nb_rx: 1 + att_tx: 12 + att_rx: 12 + bands: [78] + max_pdschReferenceSignalPower: -27 + max_rxgain: 114 + eNB_instances: [0] + bf_weights: [0x00007fff, 0x0000, 0x0000, 0x0000] + clock_src: internal + +rfsimulator: + serveraddr: server + serverport: 4043 + options: [] #("saviq"); or/and "chanmod" + modelname: AWGN + IQfile: /tmp/rfsimulator.iqs + +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: debug + f1ap_log_level: debug + +e2_agent: + near_ric_ip_addr: 127.0.0.1 + #sm_dir = /path/where/the/SMs/are/located/ + sm_dir: /usr/local/lib/flexric/ From 9b59ba6326f7e625ce067f80ad4c36eb42304bc8 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 23 Jul 2024 11:22:09 +0200 Subject: [PATCH 2/2] Enable configuration of NR UE through a YAML file This commit adds yaml-cpp library to required docker images and build commands. There is one workaround in cross-compilation for apt behavior for installing libyaml-cpp-dev. Apt will uninistall previous versions of the package whenever another one is installed. This means that installing the arm version breaks amd version and vice versa. This makes it impossible to have both libs installed at the same time which is required by the cross-compilation build command (it calls cmake twice, once with native and once with target architecture) --- ci-scripts/docker/Dockerfile.unittest.ubuntu22 | 3 ++- .../yaml_files/5g_rfsimulator/docker-compose.yaml | 2 +- cmake_targets/build_oai | 2 +- common/config/yaml/CMakeLists.txt | 3 +-- docker/Dockerfile.base.ubuntu22.cross-arm64 | 1 + docker/Dockerfile.build.ubuntu22.cross-arm64 | 2 ++ docker/Dockerfile.nrUE.rhel9 | 9 +++++++-- docker/Dockerfile.nrUE.rocky | 3 ++- docker/Dockerfile.nrUE.ubuntu22 | 6 ++++-- docker/scripts/nr_ue_entrypoint.sh | 12 ++++++++++-- 10 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ci-scripts/docker/Dockerfile.unittest.ubuntu22 b/ci-scripts/docker/Dockerfile.unittest.ubuntu22 index 4401761c02..627b0d07f7 100644 --- a/ci-scripts/docker/Dockerfile.unittest.ubuntu22 +++ b/ci-scripts/docker/Dockerfile.unittest.ubuntu22 @@ -30,7 +30,8 @@ FROM ran-base:develop AS ran-tests RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ DEBIAN_FRONTEND=noninteractive apt-get install --yes \ - libgtest-dev + libgtest-dev \ + libyaml-cpp-dev RUN rm -Rf /oai-ran WORKDIR /oai-ran diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml index 06c945a250..edee7895ca 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml @@ -118,7 +118,7 @@ services: devices: - /dev/net/tun:/dev/net/tun volumes: - - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf + - ../../conf_files/nrue.uicc.yaml:/opt/oai-nr-ue/etc/nr-ue.yaml healthcheck: test: /bin/bash -c "pgrep nr-uesoftmodem" interval: 10s diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index cd7e326be8..64ac258239 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -497,7 +497,7 @@ function main() { # add some default libraries that should always be built # for eNB, gNB, UEs, simulators if [[ $gNB == 1 || $eNB == 1 || $UE == 1 || $nrUE == 1 || $SIMUS_PHY == 1 || $RU == 1 ]]; then - TARGET_LIST="$TARGET_LIST params_libconfig coding rfsimulator dfts" + TARGET_LIST="$TARGET_LIST params_libconfig coding rfsimulator dfts params_yaml" fi mkdir -p $DIR/$BUILD_DIR/build diff --git a/common/config/yaml/CMakeLists.txt b/common/config/yaml/CMakeLists.txt index 67d90a0099..5ff8c23eb1 100644 --- a/common/config/yaml/CMakeLists.txt +++ b/common/config/yaml/CMakeLists.txt @@ -1,5 +1,4 @@ -find_package(yaml-cpp REQUIRED) - +find_package(yaml-cpp REQUIRED PATHS /usr/lib/aarch64-linux-gnu/pkgconfig/) # include(FetchContent) # FetchContent_Declare( diff --git a/docker/Dockerfile.base.ubuntu22.cross-arm64 b/docker/Dockerfile.base.ubuntu22.cross-arm64 index 74af391660..1bcba7bdd6 100644 --- a/docker/Dockerfile.base.ubuntu22.cross-arm64 +++ b/docker/Dockerfile.base.ubuntu22.cross-arm64 @@ -66,6 +66,7 @@ RUN apt-get update && \ libssl-dev:arm64 \ libtool:arm64 \ zlib1g-dev:arm64 \ + libyaml-cpp-dev:arm64 \ # cross build libs and compilers libc6-dev-i386 \ gcc-11-aarch64-linux-gnu \ diff --git a/docker/Dockerfile.build.ubuntu22.cross-arm64 b/docker/Dockerfile.build.ubuntu22.cross-arm64 index 349a4f791c..faadf79eb2 100644 --- a/docker/Dockerfile.build.ubuntu22.cross-arm64 +++ b/docker/Dockerfile.build.ubuntu22.cross-arm64 @@ -41,6 +41,8 @@ RUN /bin/sh oaienv && \ ninja ldpc_generators generate_T > ../../log/host-tools.txt 2>&1 && \ echo "====== End of log for host-tools ======" && \ cd ../build-cross/ && \ + # install missing libyaml-cpp-dev for arm64 + apt install -y libyaml-cpp-dev:arm64 && \ cmake ../../.. -GNinja -DCMAKE_TOOLCHAIN_FILE=../../../cmake_targets/cross-arm.cmake -DNATIVE_DIR=../build && \ echo "====== Start of log for cross-build executables ======" && \ # making always passing so we can analyze the all.txt file diff --git a/docker/Dockerfile.nrUE.rhel9 b/docker/Dockerfile.nrUE.rhel9 index 7279809fdb..8ab486bd85 100644 --- a/docker/Dockerfile.nrUE.rhel9 +++ b/docker/Dockerfile.nrUE.rhel9 @@ -34,6 +34,9 @@ FROM ran-build:latest AS nr-ue-build FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-nr-ue ENV TZ=Europe/Paris +# Install EPEL for RHEL9 +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + RUN dnf update -y && \ dnf install -y \ lksctp-tools \ @@ -47,7 +50,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ libXpm \ - libX11 && \ + libX11 \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -70,6 +74,7 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=nr-ue-base \ @@ -117,5 +122,5 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /tini /tini -CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/nr-ue.conf"] +CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.nrUE.rocky b/docker/Dockerfile.nrUE.rocky index ec5ecf6a99..d0455527fa 100644 --- a/docker/Dockerfile.nrUE.rocky +++ b/docker/Dockerfile.nrUE.rocky @@ -71,6 +71,7 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=nr-ue-base \ @@ -118,5 +119,5 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /tini /tini -CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/nr-ue.conf"] +CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.nrUE.ubuntu22 b/docker/Dockerfile.nrUE.ubuntu22 index 74ae9620b0..dc0d425956 100644 --- a/docker/Dockerfile.nrUE.ubuntu22 +++ b/docker/Dockerfile.nrUE.ubuntu22 @@ -64,7 +64,8 @@ RUN apt-get update && \ iputils-ping \ iproute2 \ iperf3 \ - iperf && \ + iperf \ + libyaml-cpp-dev && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ #libasan5 \ # see below @@ -97,6 +98,7 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ciUE.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ # Now we are copying from builder-image the UHD files. @@ -123,5 +125,5 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /tini /tini -CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/nr-ue.conf"] +CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/scripts/nr_ue_entrypoint.sh b/docker/scripts/nr_ue_entrypoint.sh index 31382a9b07..26ae6da7f7 100755 --- a/docker/scripts/nr_ue_entrypoint.sh +++ b/docker/scripts/nr_ue_entrypoint.sh @@ -9,8 +9,13 @@ echo "==================================" echo "/proc/sys/kernel/core_pattern=$(cat /proc/sys/kernel/core_pattern)" if [ ! -f $CONFIGFILE ]; then - echo "No configuration file found: please mount at $CONFIGFILE" - exit 255 + echo "No configuration file $CONFIGFILE found: attempting to find YAML config" + YAML_CONFIGFILE=$PREFIX/etc/nr-ue.yaml + if [ ! -f $YAML_CONFIGFILE ]; then + echo "No configuration file $YAML_CONFIGFILE found. Please mount either at $CONFIGFILE or $YAML_CONFIGFILE" + exit 255 + fi + CONFIGFILE=$YAML_CONFIGFILE fi echo "==================================" @@ -35,6 +40,9 @@ while [[ $# -gt 0 ]]; do shift done +new_args+=("-O") +new_args+=("$CONFIGFILE") + # enable printing of stack traces on assert export OAI_GDBSTACKS=1