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/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 1d04174aea..5568c159d1 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/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index af5d73e259..bcd151b086 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -590,8 +590,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 @@ -626,7 +627,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..5ff8c23eb1 --- /dev/null +++ b/common/config/yaml/CMakeLists.txt @@ -0,0 +1,25 @@ +find_package(yaml-cpp REQUIRED PATHS /usr/lib/aarch64-linux-gnu/pkgconfig/) +# 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/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 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/