From 6b0ea16a642ab7b5efa24b5a1d792347816ac0b9 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Thu, 5 Sep 2024 19:32:29 +0200 Subject: [PATCH 001/174] cmake: added splits definition to cmake --- CMakeLists.txt | 24 +++++++++++++++++++++ apps/examples/CMakeLists.txt | 7 ++++-- apps/units/flexible_du/CMakeLists.txt | 22 +++++++++++++++---- lib/CMakeLists.txt | 20 ++++++++++++----- lib/fapi_adaptor/CMakeLists.txt | 4 +++- lib/hal/CMakeLists.txt | 5 ++++- lib/phy/CMakeLists.txt | 6 ++++-- tests/benchmarks/CMakeLists.txt | 8 +++++-- tests/integrationtests/CMakeLists.txt | 8 +++++-- tests/unittests/CMakeLists.txt | 12 ++++++++--- tests/unittests/fapi_adaptor/CMakeLists.txt | 6 +++++- tests/unittests/phy/CMakeLists.txt | 6 ++++-- utils/trx_srsran/CMakeLists.txt | 4 ++++ 13 files changed, 107 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ca53a84f1..1042911ba2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -345,6 +345,30 @@ message(STATUS "TUNE value is ${MTUNE}") # Append march and mtune to the compilation flags. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${MARCH} -mtune=${MTUNE}") +######################################################################## +# DU split setup +######################################################################## +# Public variable to select the DU split. +set(DU_SPLIT_TYPE "DYNAMIC" CACHE STRING "DU split type. Default value is 'DYNAMIC'. Allowed values: DYNAMIC, SPLIT_6") + +# Internal private booleans to represent the selected DU split type. Values auto-derived from DU_SPLIT_TYPE variable. +set(DU_SPLIT_DYNAMIC OFF CACHE BOOL "DU dynamic split enabled boolean") +set(DU_SPLIT_6 OFF CACHE BOOL "DU split 6 enabled boolean") +set(DU_SPLIT_7_2 OFF CACHE BOOL "DU split 7.2 enabled boolean") +set(DU_SPLIT_8 OFF CACHE BOOL "DU split 8 enabled boolean") + +if (DU_SPLIT_TYPE STREQUAL "DYNAMIC") + set(DU_SPLIT_DYNAMIC ON) +elseif (DU_SPLIT_TYPE STREQUAL "SPLIT_6") + set(DU_SPLIT_6 ON) +else () + message(WARNING "DU split value '${DU_SPLIT_TYPE}' is not supported. Defaulting to 'DYNAMIC'") + set(DU_SPLIT_TYPE "DYNAMIC") + set(DU_SPLIT_DYNAMIC ON) +endif () + +message(STATUS "Selected DU split is '${DU_SPLIT_TYPE}'") + ######################################################################## # Compiler launcher setup ######################################################################## diff --git a/apps/examples/CMakeLists.txt b/apps/examples/CMakeLists.txt index 3ce35a8f02..dd2ff8ffa3 100644 --- a/apps/examples/CMakeLists.txt +++ b/apps/examples/CMakeLists.txt @@ -6,5 +6,8 @@ # the distribution. # -add_subdirectory(phy) -add_subdirectory(radio) +if (DU_SPLIT_8 OR DU_SPLIT_DYNAMIC) + add_subdirectory(phy) + add_subdirectory(radio) +endif () + diff --git a/apps/units/flexible_du/CMakeLists.txt b/apps/units/flexible_du/CMakeLists.txt index c90ec9b658..4726358073 100644 --- a/apps/units/flexible_du/CMakeLists.txt +++ b/apps/units/flexible_du/CMakeLists.txt @@ -7,9 +7,23 @@ # add_subdirectory(du_high) -add_subdirectory(du_low) add_subdirectory(fapi) -add_subdirectory(split_7_2) -add_subdirectory(split_8) -add_subdirectory(split_dynamic) add_subdirectory(support) +if (DU_SPLIT_6) + add_subdirectory(split_6) +endif () +if (DU_SPLIT_7_2) + add_subdirectory(du_low) + add_subdirectory(split_7_2) +endif () +if (DU_SPLIT_8) + add_subdirectory(du_low) + add_subdirectory(split_8) +endif () +if (DU_SPLIT_DYNAMIC) + add_subdirectory(du_low) + add_subdirectory(split_7_2) + add_subdirectory(split_8) + add_subdirectory(split_dynamic) +endif () + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5c55016538..cfc2eda93e 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -11,7 +11,9 @@ add_subdirectory(cu_cp) add_subdirectory(cu_up) add_subdirectory(du) add_subdirectory(du_high) -add_subdirectory(du_low) +if (NOT DU_SPLIT_6) + add_subdirectory(du_low) +endif () add_subdirectory(du_manager) add_subdirectory(e1ap) add_subdirectory(e2) @@ -28,16 +30,24 @@ endif (DPDK_FOUND) add_subdirectory(mac) add_subdirectory(ngap) add_subdirectory(nru) -add_subdirectory(ofh) +if (DU_SPLIT_7_2 OR DU_SPLIT_DYNAMIC) + add_subdirectory(ofh) +endif () add_subdirectory(pcap) add_subdirectory(pdcp) -add_subdirectory(phy) +if (NOT DU_SPLIT_6) + add_subdirectory(phy) +endif () add_subdirectory(psup) -add_subdirectory(radio) +if (DU_SPLIT_DYNAMIC OR DU_SPLIT_8) + add_subdirectory(radio) +endif () add_subdirectory(ran) add_subdirectory(rlc) add_subdirectory(rrc) -add_subdirectory(ru) +if (NOT DU_SPLIT_6) + add_subdirectory(ru) +endif () add_subdirectory(scheduler) add_subdirectory(sdap) add_subdirectory(security) diff --git a/lib/fapi_adaptor/CMakeLists.txt b/lib/fapi_adaptor/CMakeLists.txt index 34c1d2672a..c65dcea30c 100644 --- a/lib/fapi_adaptor/CMakeLists.txt +++ b/lib/fapi_adaptor/CMakeLists.txt @@ -7,7 +7,9 @@ # add_subdirectory(mac) -add_subdirectory(phy) +if (NOT DU_SPLIT_6) + add_subdirectory(phy) +endif () set(PRECODING_SOURCES precoding_matrix_mapper.cpp diff --git a/lib/hal/CMakeLists.txt b/lib/hal/CMakeLists.txt index e550f28b88..e39ecc0dc4 100644 --- a/lib/hal/CMakeLists.txt +++ b/lib/hal/CMakeLists.txt @@ -7,4 +7,7 @@ # add_subdirectory(dpdk) -add_subdirectory(phy) +if (NOT DU_SPLIT_6) + add_subdirectory(phy) +endif () + diff --git a/lib/phy/CMakeLists.txt b/lib/phy/CMakeLists.txt index 0d3f6c9bf3..7032e7a101 100644 --- a/lib/phy/CMakeLists.txt +++ b/lib/phy/CMakeLists.txt @@ -7,6 +7,8 @@ # add_subdirectory(generic_functions) -add_subdirectory(lower) add_subdirectory(support) -add_subdirectory(upper) \ No newline at end of file +add_subdirectory(upper) +if (DU_SPLIT_8 OR DU_SPLIT_DYNAMIC) + add_subdirectory(lower) +endif () diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt index 6387d0f0ea..8e151b0689 100644 --- a/tests/benchmarks/CMakeLists.txt +++ b/tests/benchmarks/CMakeLists.txt @@ -11,9 +11,13 @@ remove_definitions(-DPARANOID_ASSERTS_ENABLED) add_subdirectory(adt) add_subdirectory(gateways) -add_subdirectory(phy) +if (NOT DU_SPLIT_6) + add_subdirectory(phy) +endif () add_subdirectory(scheduler) add_subdirectory(du_high) -add_subdirectory(ofh) +if (DU_SPLIT_7_2 OR DU_SPLIT_DYNAMIC) + add_subdirectory(ofh) +endif () add_subdirectory(rlc) add_subdirectory(pdcp) diff --git a/tests/integrationtests/CMakeLists.txt b/tests/integrationtests/CMakeLists.txt index 674cc500a7..8913777989 100644 --- a/tests/integrationtests/CMakeLists.txt +++ b/tests/integrationtests/CMakeLists.txt @@ -10,6 +10,10 @@ add_subdirectory(du_high) add_subdirectory(du_high_cu) add_subdirectory(e2ap) add_subdirectory(ngap) -add_subdirectory(ofh) -add_subdirectory(phy) +if (DU_SPLIT_7_2 OR DU_SPLIT_DYNAMIC) + add_subdirectory(ofh) +endif () +if (NOT DU_SPLIT_6) + add_subdirectory(phy) +endif () add_subdirectory(rlc) diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt index 189681af39..2fbd35845e 100644 --- a/tests/unittests/CMakeLists.txt +++ b/tests/unittests/CMakeLists.txt @@ -57,12 +57,18 @@ add_subdirectory(gtpu) add_subdirectory(mac) add_subdirectory(ngap) add_subdirectory(nru) -add_subdirectory(ofh) +if (DU_SPLIT_7_2 OR DU_SPLIT_DYNAMIC) + add_subdirectory(ofh) +endif () add_subdirectory(pcap) add_subdirectory(pdcp) -add_subdirectory(phy) +if (NOT DU_SPLIT_6) + add_subdirectory(phy) +endif () add_subdirectory(psup) -add_subdirectory(radio) +if (DU_SPLIT_DYNAMIC OR DU_SPLIT_8) + add_subdirectory(radio) +endif () add_subdirectory(ran) add_subdirectory(rlc) add_subdirectory(rrc) diff --git a/tests/unittests/fapi_adaptor/CMakeLists.txt b/tests/unittests/fapi_adaptor/CMakeLists.txt index d4a7fa337a..fde4aef23d 100644 --- a/tests/unittests/fapi_adaptor/CMakeLists.txt +++ b/tests/unittests/fapi_adaptor/CMakeLists.txt @@ -9,11 +9,15 @@ set_directory_properties(PROPERTIES LABELS "fapi_adaptor") add_subdirectory(mac) -add_subdirectory(phy) +if (NOT DU_SPLIT_6) + add_subdirectory(phy) +endif () +if (NOT DU_SPLIT_6) add_executable(fapi_adaptor_performance_dl_tti_request adaptor_performance_dl_tti_request.cpp) target_link_libraries(fapi_adaptor_performance_dl_tti_request srsran_fapi_phy_message_adaptors srsran_mac_fapi_adaptors srslog) add_test(fapi_adaptor_performance_dl_tti_request fapi_adaptor_performance_dl_tti_request) +endif () add_executable(precoding_matrix_table_generator_test precoding_matrix_table_generator_test.cpp) target_link_libraries(precoding_matrix_table_generator_test srsran_fapi_precoding_matrix_tools srslog gtest gtest_main) diff --git a/tests/unittests/phy/CMakeLists.txt b/tests/unittests/phy/CMakeLists.txt index a96a98ec52..a16f1fcc4b 100644 --- a/tests/unittests/phy/CMakeLists.txt +++ b/tests/unittests/phy/CMakeLists.txt @@ -7,6 +7,8 @@ # add_subdirectory(generic_functions) -add_subdirectory(lower) +if (DU_SPLIT_8 OR DU_SPLIT_DYNAMIC) + add_subdirectory(lower) +endif () add_subdirectory(upper) -add_subdirectory(support) \ No newline at end of file +add_subdirectory(support) diff --git a/utils/trx_srsran/CMakeLists.txt b/utils/trx_srsran/CMakeLists.txt index e86261eb3c..eccb908c7b 100644 --- a/utils/trx_srsran/CMakeLists.txt +++ b/utils/trx_srsran/CMakeLists.txt @@ -17,6 +17,10 @@ if (NOT ENABLE_EXPORT) message(SEND_ERROR "Enable export is required. Append -DENABLE_EXPORT=TRUE to the cmake arguments.") endif () +if (NOT DU_SPLIT_DYNAMIC OR DU_SPLIT_8) + message(SEND_ERROR "Dynamic split or split 8 is required. Append -DDU_SPLIT_TYPE=DYNAMIC or -DDU_SPLIT_TYPE=SPLIT_8 to the cmake arguments.") +endif () + # Add shared library. add_library(trx_srsran SHARED trx_srsran.cpp) From d79874ba6c07b47c712bb9e32f9afbb140a2d831 Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 9 Sep 2024 17:19:10 +0200 Subject: [PATCH 002/174] Move simd.h to public as it is being used by different implementations --- {lib => include/srsran}/srsvec/simd.h | 0 lib/phy/generic_functions/dft_processor_generic_impl.cpp | 2 +- lib/phy/upper/equalization/equalize_mmse_1xn.h | 2 +- lib/phy/upper/equalization/equalize_zf_1xn.h | 2 +- lib/phy/upper/equalization/equalize_zf_2xn.h | 2 +- lib/srsvec/accumulate.cpp | 2 +- lib/srsvec/add.cpp | 2 +- lib/srsvec/aligned_vec.cpp | 2 +- lib/srsvec/compare.cpp | 4 ++-- lib/srsvec/conversion.cpp | 4 ++-- lib/srsvec/convolution.cpp | 2 +- lib/srsvec/division.cpp | 2 +- lib/srsvec/dot_prod.cpp | 2 +- lib/srsvec/modulus_square.cpp | 2 +- lib/srsvec/prod.cpp | 2 +- lib/srsvec/sc_prod.cpp | 2 +- lib/srsvec/subtract.cpp | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) rename {lib => include/srsran}/srsvec/simd.h (100%) diff --git a/lib/srsvec/simd.h b/include/srsran/srsvec/simd.h similarity index 100% rename from lib/srsvec/simd.h rename to include/srsran/srsvec/simd.h diff --git a/lib/phy/generic_functions/dft_processor_generic_impl.cpp b/lib/phy/generic_functions/dft_processor_generic_impl.cpp index d489e14678..c2c990488c 100644 --- a/lib/phy/generic_functions/dft_processor_generic_impl.cpp +++ b/lib/phy/generic_functions/dft_processor_generic_impl.cpp @@ -9,7 +9,7 @@ */ #include "dft_processor_generic_impl.h" -#include "../../srsvec/simd.h" +#include "srsran/srsvec/simd.h" #include "srsran/support/math_utils.h" using namespace srsran; diff --git a/lib/phy/upper/equalization/equalize_mmse_1xn.h b/lib/phy/upper/equalization/equalize_mmse_1xn.h index 1759f93c66..a9d1d90e75 100644 --- a/lib/phy/upper/equalization/equalize_mmse_1xn.h +++ b/lib/phy/upper/equalization/equalize_mmse_1xn.h @@ -13,7 +13,7 @@ #pragma once -#include "../../../srsvec/simd.h" +#include "srsran/srsvec/simd.h" #include "srsran/srsvec/zero.h" namespace srsran { diff --git a/lib/phy/upper/equalization/equalize_zf_1xn.h b/lib/phy/upper/equalization/equalize_zf_1xn.h index cbb798e3c7..9a090c3894 100644 --- a/lib/phy/upper/equalization/equalize_zf_1xn.h +++ b/lib/phy/upper/equalization/equalize_zf_1xn.h @@ -13,9 +13,9 @@ #pragma once -#include "../../../srsvec/simd.h" #include "srsran/phy/constants.h" #include "srsran/srsvec/fill.h" +#include "srsran/srsvec/simd.h" #include "srsran/srsvec/zero.h" namespace srsran { diff --git a/lib/phy/upper/equalization/equalize_zf_2xn.h b/lib/phy/upper/equalization/equalize_zf_2xn.h index cb6875292e..b001c36623 100644 --- a/lib/phy/upper/equalization/equalize_zf_2xn.h +++ b/lib/phy/upper/equalization/equalize_zf_2xn.h @@ -13,7 +13,7 @@ #pragma once -#include "../../../srsvec/simd.h" +#include "srsran/srsvec/simd.h" #include "srsran/srsvec/zero.h" namespace srsran { diff --git a/lib/srsvec/accumulate.cpp b/lib/srsvec/accumulate.cpp index 81e3c1bece..549b264ca9 100644 --- a/lib/srsvec/accumulate.cpp +++ b/lib/srsvec/accumulate.cpp @@ -8,7 +8,7 @@ * */ #include "srsran/srsvec/accumulate.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" #include "srsran/support/srsran_assert.h" #include diff --git a/lib/srsvec/add.cpp b/lib/srsvec/add.cpp index ca38e9022e..5257c2b559 100644 --- a/lib/srsvec/add.cpp +++ b/lib/srsvec/add.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/add.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; diff --git a/lib/srsvec/aligned_vec.cpp b/lib/srsvec/aligned_vec.cpp index 62bac92e97..cdf42c26e8 100644 --- a/lib/srsvec/aligned_vec.cpp +++ b/lib/srsvec/aligned_vec.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/aligned_vec.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" #include "srsran/support/error_handling.h" #include diff --git a/lib/srsvec/compare.cpp b/lib/srsvec/compare.cpp index a329494f9b..2e1bbfd844 100644 --- a/lib/srsvec/compare.cpp +++ b/lib/srsvec/compare.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/compare.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" #include "srsran/support/math_utils.h" #include @@ -245,4 +245,4 @@ unsigned srsran::srsvec::count_if_part_abs_greater_than(span return count + std::count_if(x.begin(), x.end(), [threshold](cf_t sample) { return (std::abs(sample.real()) > threshold) || (std::abs(sample.imag()) > threshold); }); -} \ No newline at end of file +} diff --git a/lib/srsvec/conversion.cpp b/lib/srsvec/conversion.cpp index c9faec2b5d..f5b2d9c724 100644 --- a/lib/srsvec/conversion.cpp +++ b/lib/srsvec/conversion.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/conversion.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; @@ -543,4 +543,4 @@ void srsran::srsvec::convert(span z, span x, float scale) srsran_assert(x.size() == z.size(), "Invalid input or output span sizes"); convert_int16_to_bf16_simd(z.data(), x.data(), scale, z.size()); -} \ No newline at end of file +} diff --git a/lib/srsvec/convolution.cpp b/lib/srsvec/convolution.cpp index b7a2d94d23..3e67d89917 100644 --- a/lib/srsvec/convolution.cpp +++ b/lib/srsvec/convolution.cpp @@ -10,7 +10,7 @@ */ #include "srsran/srsvec/convolution.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; diff --git a/lib/srsvec/division.cpp b/lib/srsvec/division.cpp index ed888060ce..81d3589eb8 100644 --- a/lib/srsvec/division.cpp +++ b/lib/srsvec/division.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/division.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; diff --git a/lib/srsvec/dot_prod.cpp b/lib/srsvec/dot_prod.cpp index c362a3a8f7..78e6ac31b6 100644 --- a/lib/srsvec/dot_prod.cpp +++ b/lib/srsvec/dot_prod.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/dot_prod.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; diff --git a/lib/srsvec/modulus_square.cpp b/lib/srsvec/modulus_square.cpp index 9aac36d415..02a3d2dc85 100644 --- a/lib/srsvec/modulus_square.cpp +++ b/lib/srsvec/modulus_square.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/modulus_square.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; diff --git a/lib/srsvec/prod.cpp b/lib/srsvec/prod.cpp index b3527552b6..175f31a8be 100644 --- a/lib/srsvec/prod.cpp +++ b/lib/srsvec/prod.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/prod.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" #include using namespace srsran; diff --git a/lib/srsvec/sc_prod.cpp b/lib/srsvec/sc_prod.cpp index 44ed3f72a4..90a167af12 100644 --- a/lib/srsvec/sc_prod.cpp +++ b/lib/srsvec/sc_prod.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/sc_prod.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; diff --git a/lib/srsvec/subtract.cpp b/lib/srsvec/subtract.cpp index 86b7cd994d..faa647bafa 100644 --- a/lib/srsvec/subtract.cpp +++ b/lib/srsvec/subtract.cpp @@ -9,7 +9,7 @@ */ #include "srsran/srsvec/subtract.h" -#include "simd.h" +#include "srsran/srsvec/simd.h" using namespace srsran; using namespace srsvec; From f8012053ef97baec672b7d23670bbc7ef46fedc6 Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 9 Sep 2024 17:33:56 +0200 Subject: [PATCH 003/174] Move resource_grid_dimensions.h file to public as it is being used by the ru_dummy library --- {lib => include/srsran}/phy/support/resource_grid_dimensions.h | 0 lib/phy/support/resource_grid_impl.h | 2 +- lib/phy/support/resource_grid_reader_impl.h | 2 +- lib/phy/support/resource_grid_writer_impl.h | 2 +- lib/ru/dummy/ru_dummy_rx_resource_grid.h | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename {lib => include/srsran}/phy/support/resource_grid_dimensions.h (100%) diff --git a/lib/phy/support/resource_grid_dimensions.h b/include/srsran/phy/support/resource_grid_dimensions.h similarity index 100% rename from lib/phy/support/resource_grid_dimensions.h rename to include/srsran/phy/support/resource_grid_dimensions.h diff --git a/lib/phy/support/resource_grid_impl.h b/lib/phy/support/resource_grid_impl.h index 98f4bc8530..58822c05f8 100644 --- a/lib/phy/support/resource_grid_impl.h +++ b/lib/phy/support/resource_grid_impl.h @@ -10,13 +10,13 @@ #pragma once -#include "resource_grid_dimensions.h" #include "resource_grid_mapper_impl.h" #include "resource_grid_reader_impl.h" #include "resource_grid_writer_impl.h" #include "srsran/adt/tensor.h" #include "srsran/phy/generic_functions/precoding/channel_precoder.h" #include "srsran/phy/support/resource_grid.h" +#include "srsran/phy/support/resource_grid_dimensions.h" namespace srsran { diff --git a/lib/phy/support/resource_grid_reader_impl.h b/lib/phy/support/resource_grid_reader_impl.h index a234269849..31f81d740d 100644 --- a/lib/phy/support/resource_grid_reader_impl.h +++ b/lib/phy/support/resource_grid_reader_impl.h @@ -9,7 +9,7 @@ */ #pragma once -#include "resource_grid_dimensions.h" +#include "srsran/phy/support/resource_grid_dimensions.h" #include "srsran/phy/support/resource_grid_reader.h" namespace srsran { diff --git a/lib/phy/support/resource_grid_writer_impl.h b/lib/phy/support/resource_grid_writer_impl.h index 26d5d34514..fb89d69b79 100644 --- a/lib/phy/support/resource_grid_writer_impl.h +++ b/lib/phy/support/resource_grid_writer_impl.h @@ -9,7 +9,7 @@ */ #pragma once -#include "resource_grid_dimensions.h" +#include "srsran/phy/support/resource_grid_dimensions.h" #include "srsran/phy/support/resource_grid_writer.h" namespace srsran { diff --git a/lib/ru/dummy/ru_dummy_rx_resource_grid.h b/lib/ru/dummy/ru_dummy_rx_resource_grid.h index f8efad18c2..40ee1bbc1a 100644 --- a/lib/ru/dummy/ru_dummy_rx_resource_grid.h +++ b/lib/ru/dummy/ru_dummy_rx_resource_grid.h @@ -10,8 +10,8 @@ #pragma once -#include "../../phy/support/resource_grid_dimensions.h" #include "srsran/adt/tensor.h" +#include "srsran/phy/support/resource_grid_dimensions.h" #include "srsran/phy/support/resource_grid_reader.h" #include "srsran/srsvec/conversion.h" #include "srsran/srsvec/copy.h" From 420f08627f757e69cc736fbed6a21da1ddf840ba Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Wed, 4 Sep 2024 18:31:51 +0200 Subject: [PATCH 004/174] flexible_du: added split 6 objects --- apps/du/du.cpp | 24 ++-- apps/gnb/gnb.cpp | 24 ++-- apps/units/flexible_du/du_high/pcap_factory.h | 2 +- apps/units/flexible_du/du_unit.h | 58 ++++++++ apps/units/flexible_du/split_6/CMakeLists.txt | 23 ++++ .../split6_du_application_unit_impl.cpp | 47 +++++++ .../split_6/split6_du_application_unit_impl.h | 41 ++++++ .../flexible_du/split_6/split6_du_factory.cpp | 126 ++++++++++++++++++ .../flexible_du/split_6/split6_du_factory.h | 30 +++++ .../flexible_du/split_6/split6_du_impl.cpp | 56 ++++++++ .../flexible_du/split_6/split6_du_impl.h | 40 ++++++ .../split_6/split6_du_unit_cli11_schema.cpp | 27 ++++ .../split_6/split6_du_unit_cli11_schema.h | 25 ++++ .../split_6/split6_du_unit_config.h | 26 ++++ .../split6_du_unit_config_validator.cpp | 24 ++++ .../split_6/split6_du_unit_config_validator.h | 21 +++ ....h => split6_du_unit_logger_registrator.h} | 16 +-- .../units/flexible_du/split_6/split6_plugin.h | 44 ++++++ .../split_7_2/ru_ofh_config_validator.h | 2 +- .../split_dynamic/dynamic_du_factory.cpp | 40 +++--- .../split_dynamic/dynamic_du_factory.h | 25 +--- include/srsran/fapi_adaptor/fapi_adaptor.h | 76 +++++++++++ lib/du/du_wrapper_factory.cpp | 2 +- 23 files changed, 715 insertions(+), 84 deletions(-) create mode 100644 apps/units/flexible_du/du_unit.h create mode 100644 apps/units/flexible_du/split_6/CMakeLists.txt create mode 100644 apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp create mode 100644 apps/units/flexible_du/split_6/split6_du_application_unit_impl.h create mode 100644 apps/units/flexible_du/split_6/split6_du_factory.cpp create mode 100644 apps/units/flexible_du/split_6/split6_du_factory.h create mode 100644 apps/units/flexible_du/split_6/split6_du_impl.cpp create mode 100644 apps/units/flexible_du/split_6/split6_du_impl.h create mode 100644 apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.cpp create mode 100644 apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.h create mode 100644 apps/units/flexible_du/split_6/split6_du_unit_config.h create mode 100644 apps/units/flexible_du/split_6/split6_du_unit_config_validator.cpp create mode 100644 apps/units/flexible_du/split_6/split6_du_unit_config_validator.h rename apps/units/flexible_du/split_6/{logger_registrator.h => split6_du_unit_logger_registrator.h} (51%) create mode 100644 apps/units/flexible_du/split_6/split6_plugin.h create mode 100644 include/srsran/fapi_adaptor/fapi_adaptor.h diff --git a/apps/du/du.cpp b/apps/du/du.cpp index 2209b7ffeb..6cd06591cd 100644 --- a/apps/du/du.cpp +++ b/apps/du/du.cpp @@ -298,17 +298,19 @@ int main(int argc, char** argv) e2_gateway_remote_connector e2_gw{*epoll_broker, e2_du_nw_config, *du_pcaps.e2ap}; app_services::metrics_notifier_proxy_impl metrics_notifier_forwarder; - auto du_inst_and_cmds = create_du(du_unit_cfg, - workers, - *f1c_gw, - *du_f1u_conn, - app_timers, - *du_pcaps.mac, - *du_pcaps.rlc, - e2_gw, - e2_metric_connectors, - json_sink, - metrics_notifier_forwarder); + du_unit_dependencies du_dependencies; + du_dependencies.workers = &workers; + du_dependencies.f1c_client_handler = f1c_gw.get(); + du_dependencies.f1u_gw = du_f1u_conn.get(); + du_dependencies.timer_mng = &app_timers; + du_dependencies.mac_p = du_pcaps.mac.get(); + du_dependencies.rlc_p = du_pcaps.rlc.get(); + du_dependencies.e2_client_handler = &e2_gw; + du_dependencies.e2_metric_connectors = &e2_metric_connectors; + du_dependencies.json_sink = &json_sink; + du_dependencies.metrics_notifier = &metrics_notifier_forwarder; + + auto du_inst_and_cmds = create_du(du_unit_cfg, du_dependencies); // Only DU has metrics now. app_services::metrics_manager metrics_mngr( diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 9cba8e86a4..7598f9e253 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -410,17 +410,19 @@ int main(int argc, char** argv) // Instantiate one DU. app_services::metrics_notifier_proxy_impl metrics_notifier_forwarder; - auto du_inst_and_cmds = create_du(du_unit_cfg, - workers, - *f1c_gw, - *f1u_conn->get_f1u_du_gateway(), - app_timers, - *du_pcaps.mac, - *du_pcaps.rlc, - e2_gw, - e2_metric_connectors, - json_sink, - metrics_notifier_forwarder); + du_unit_dependencies du_dependencies; + du_dependencies.workers = &workers; + du_dependencies.f1c_client_handler = f1c_gw.get(); + du_dependencies.f1u_gw = f1u_conn->get_f1u_du_gateway(); + du_dependencies.timer_mng = &app_timers; + du_dependencies.mac_p = du_pcaps.mac.get(); + du_dependencies.rlc_p = du_pcaps.rlc.get(); + du_dependencies.e2_client_handler = &e2_gw; + du_dependencies.e2_metric_connectors = &e2_metric_connectors; + du_dependencies.json_sink = &json_sink; + du_dependencies.metrics_notifier = &metrics_notifier_forwarder; + + auto du_inst_and_cmds = create_du(du_unit_cfg, du_dependencies); du& du_inst = *du_inst_and_cmds.unit; diff --git a/apps/units/flexible_du/du_high/pcap_factory.h b/apps/units/flexible_du/du_high/pcap_factory.h index 5aef3218a3..39889dd693 100644 --- a/apps/units/flexible_du/du_high/pcap_factory.h +++ b/apps/units/flexible_du/du_high/pcap_factory.h @@ -10,7 +10,7 @@ #pragma once -#include "../../../services/worker_manager.h" +#include "apps/services/worker_manager.h" #include "srsran/pcap/dlt_pcap.h" #include "srsran/pcap/mac_pcap.h" #include "srsran/pcap/rlc_pcap.h" diff --git a/apps/units/flexible_du/du_unit.h b/apps/units/flexible_du/du_unit.h new file mode 100644 index 0000000000..f84d5817de --- /dev/null +++ b/apps/units/flexible_du/du_unit.h @@ -0,0 +1,58 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/services/application_command.h" +#include "apps/services/metrics/metrics_config.h" +#include "srsran/du/du.h" +#include +#include + +namespace srsran { + +namespace app_services { +class metrics_notifier; +} // namespace app_services + +namespace srs_du { +class f1u_du_gateway; +class f1c_connection_client; +} // namespace srs_du + +class e2_connection_client; +class e2_metric_connector_manager; +class mac_pcap; +class rlc_pcap; +class timer_manager; +struct worker_manager; + +/// Wraps the DU and its supported application commands. +struct du_unit { + std::unique_ptr unit; + std::vector> commands; + std::vector metrics; +}; + +/// DU unit dependencies. +struct du_unit_dependencies { + worker_manager* workers = nullptr; + srs_du::f1c_connection_client* f1c_client_handler = nullptr; + srs_du::f1u_du_gateway* f1u_gw = nullptr; + timer_manager* timer_mng = nullptr; + mac_pcap* mac_p = nullptr; + rlc_pcap* rlc_p = nullptr; + e2_connection_client* e2_client_handler = nullptr; + e2_metric_connector_manager* e2_metric_connectors = nullptr; + srslog::sink* json_sink = nullptr; + app_services::metrics_notifier* metrics_notifier = nullptr; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/CMakeLists.txt b/apps/units/flexible_du/split_6/CMakeLists.txt new file mode 100644 index 0000000000..3bc1262b8d --- /dev/null +++ b/apps/units/flexible_du/split_6/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +set(SOURCES + split6_du_application_unit_impl.cpp + split6_du_factory.cpp + split6_du_impl.cpp + split6_du_unit_cli11_schema.cpp + split6_du_unit_config_validator.cpp) + +add_library(srsran_flexible_du_split6 STATIC ${SOURCES}) +target_include_directories(srsran_flexible_du_split6 PRIVATE ${CMAKE_SOURCE_DIR}) +target_link_libraries(srsran_flexible_du_split6 + srsran_du_high_wrapper + srsran_pcap + srsran_app_services + srsran_fapi_app_unit + srsran_du_high_unit_helpers) diff --git a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp new file mode 100644 index 0000000000..3e5cd26357 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp @@ -0,0 +1,47 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split6_du_application_unit_impl.h" +#include "split6_du_factory.h" +#include "split6_du_unit_cli11_schema.h" +#include "split6_du_unit_logger_registrator.h" + +using namespace srsran; + +void split6_du_application_unit_impl::on_loggers_registration() +{ + register_split6_du_loggers(unit_cfg); + plugin->on_loggers_registration(); +} + +bool split6_du_application_unit_impl::on_configuration_validation() const +{ + if (!plugin->on_configuration_validation()) { + return false; + } + + return true; +} + +void split6_du_application_unit_impl::on_parsing_configuration_registration(CLI::App& app) +{ + configure_cli11_with_split6_du_unit_config_schema(app, unit_cfg); + plugin->on_parsing_configuration_registration(app); +} + +du_unit split6_du_application_unit_impl::create_unit(const du_unit_dependencies& dependencies) +{ + auto fapi_ctrl = plugin->create_fapi_adaptor(dependencies); + report_error_if_not(!fapi_ctrl.empty(), "Could not create FAPI adaptor"); + auto du_impl = create_du_split6(unit_cfg, dependencies, std::move(fapi_ctrl)); + report_error_if_not(du_impl.unit, "Could not create split 6 DU"); + + return du_impl; +} diff --git a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.h b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.h new file mode 100644 index 0000000000..1e9fd20bc0 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/application_unit.h" +#include "apps/units/flexible_du/du_unit.h" +#include "split6_du_unit_config.h" +#include "split6_plugin.h" + +namespace srsran { + +/// DU Split6 application unit implementation. +class split6_du_application_unit_impl : public application_unit +{ +public: + // See interface for documentation. + void on_parsing_configuration_registration(CLI::App& app) override; + + // See interface for documentation. + bool on_configuration_validation() const override; + + // See interface for documentation. + void on_loggers_registration() override; + + /// Creates the DU unit. + du_unit create_unit(const du_unit_dependencies& dependencies); + +private: + split6_du_unit_config unit_cfg; + std::unique_ptr plugin; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/split6_du_factory.cpp b/apps/units/flexible_du/split_6/split6_du_factory.cpp new file mode 100644 index 0000000000..7b47c447a7 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_factory.cpp @@ -0,0 +1,126 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split6_du_factory.h" +#include "apps/services/e2_metric_connector_manager.h" +#include "apps/services/worker_manager.h" +#include "apps/units/flexible_du/du_high/du_high_commands.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h" +#include "apps/units/flexible_du/flexible_du_commands.h" +#include "split6_du_impl.h" +#include "split6_du_unit_config.h" +#include "srsran/du/du_high_wrapper.h" +#include "srsran/du/du_high_wrapper_factory.h" + +using namespace srsran; + +/// \brief Update the Flexible DU metrics configuration with the given local DU configuration and E2 configuration. +/// +/// This function manages the multicell workaround for the DU high metrics. To have multicell, now one DU is +/// instantiated per cell, so the this would create multiple consumers that does not make sense, for example stdout. +/// With this we avoid having 2 different objects that write in the stdout. +static void update_du_metrics(std::vector& flexible_du_cfg, + std::vector local_du_cfg, + bool is_e2_enabled) +{ + // First call, copy everything. + if (flexible_du_cfg.empty()) { + flexible_du_cfg = std::move(local_du_cfg); + return; + } + + // Safe check that all the DUs provides the same amount of metrics. + srsran_assert(flexible_du_cfg.size() == local_du_cfg.size(), + "Flexible DU metrics size '{}' does not match DU metrics size '{}'", + flexible_du_cfg.size(), + local_du_cfg.size()); + + // Iterate the metrics configs of each DU. Each DU should ha + for (unsigned i = 0, e = local_du_cfg.size(); i != e; ++i) { + // Store the metrics producers for each DU. + flexible_du_cfg[i].producers.push_back(std::move(local_du_cfg[i].producers.back())); + + // Move E2 consumers for each DU to the common output config. E2 Consumers occupy the last position. + if (is_e2_enabled) { + flexible_du_cfg[i].consumers.push_back(std::move(local_du_cfg[i].consumers.back())); + } + } +} + +du_unit srsran::create_du_split6(const split6_du_unit_config& du_unit_cfg, + const du_unit_dependencies& du_dependencies, + std::vector> fapi_adaptors) +{ + du_unit du_cmd_wrapper; + + const du_high_unit_config& du_hi = du_unit_cfg.du_high_cfg.config; + const fapi_unit_config& fapi_cfg = du_unit_cfg.fapi_cfg; + + auto du_cells = generate_du_cell_config(du_hi); + + std::vector> du_insts; + for (unsigned i = 0, e = du_cells.size(); i != e; ++i) { + // Create one DU per cell. + du_high_wrapper_config du_cfg = {}; + du_high_unit_config tmp_cfg = du_hi; + tmp_cfg.cells_cfg.resize(1); + tmp_cfg.cells_cfg[0] = du_hi.cells_cfg[i]; + + auto cell_services_cfg = fill_du_high_wrapper_config(du_cfg, + tmp_cfg, + i, + du_dependencies.workers->get_du_high_executor_mapper(i), + *du_dependencies.f1c_client_handler, + *du_dependencies.f1u_gw, + *du_dependencies.timer_mng, + *du_dependencies.mac_p, + *du_dependencies.rlc_p, + *du_dependencies.e2_client_handler, + *du_dependencies.e2_metric_connectors, + *du_dependencies.json_sink, + *du_dependencies.metrics_notifier); + + update_du_metrics(du_cmd_wrapper.metrics, std::move(cell_services_cfg.first), tmp_cfg.e2_cfg.enable_du_e2); + + // Use the commands of the first cell. + if (i == 0) { + for (auto& command : cell_services_cfg.second) + du_cmd_wrapper.commands.push_back(std::move(command)); + } + + // FAPI configuration. + du_cfg.fapi.log_level = fapi_cfg.fapi_level; + if (fapi_cfg.l2_nof_slots_ahead != 0) { + // As the temporal configuration contains only one cell, pick the data from that cell. + du_cfg.fapi.l2_nof_slots_ahead = fapi_cfg.l2_nof_slots_ahead; + du_cfg.fapi.executor.emplace(du_dependencies.workers->fapi_exec[i]); + } else { + report_error_if_not(du_dependencies.workers->fapi_exec[i] == nullptr, + "FAPI buffered worker created for a cell with no MAC delay configured"); + } + + du_high_wrapper_dependencies sector_dependencies; + sector_dependencies.sectors.push_back( + {&fapi_adaptors[i]->get_message_interface_collection().get_slot_message_gateway(), + &fapi_adaptors[i]->get_message_interface_collection().get_slot_last_message_notifier()}); + + du_insts.push_back(make_du_high_wrapper(du_cfg, std::move(sector_dependencies))); + report_error_if_not(du_insts.back(), "Invalid Distributed Unit wrapper"); + } + + // Create the DU. + du_cmd_wrapper.unit = std::make_unique(std::move(fapi_adaptors), std::move(du_insts)); + report_error_if_not(du_cmd_wrapper.unit, "Invalid Distributed Unit"); + + announce_du_high_cells(du_hi); + + return du_cmd_wrapper; +} diff --git a/apps/units/flexible_du/split_6/split6_du_factory.h b/apps/units/flexible_du/split_6/split6_du_factory.h new file mode 100644 index 0000000000..f0c41a325a --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_factory.h @@ -0,0 +1,30 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_unit.h" +#include +#include + +namespace srsran { + +namespace fapi { +class fapi_adaptor; +} // namespace fapi + +struct split6_du_unit_config; + +/// Helper function to build the DU Split 6 with the given arguments. +du_unit create_du_split6(const split6_du_unit_config& du_unit_cfg, + const du_unit_dependencies& du_dependencies, + std::vector> fapi_adaptors); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/split6_du_impl.cpp b/apps/units/flexible_du/split_6/split6_du_impl.cpp new file mode 100644 index 0000000000..3f8a4c935b --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_impl.cpp @@ -0,0 +1,56 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split6_du_impl.h" + +#include "srsran/support/srsran_assert.h" + +using namespace srsran; + +split6_du_impl::split6_du_impl(std::vector> adaptors_, + std::vector> du_list_) : + du_list(std::move(du_list_)), adaptors(std::move(adaptors_)) +{ + srsran_assert(!du_list.empty(), "Invalid DU high wrapper"); + srsran_assert(adaptors.size() == du_list.size(), "Number of FAPI adaptors does not match number of DUs"); + + // Hardcoded 0 is because at this moment there is one DU instance with one cell per cell, so we can always access the + // cell id 0 of the DU. + for (unsigned i = 0, e = du_list.size(); i != e; ++i) { + adaptors[i]->get_message_interface_collection().set_slot_data_message_notifier( + du_list[i]->get_slot_data_message_notifier(0)); + adaptors[i]->get_message_interface_collection().set_slot_error_message_notifier( + du_list[i]->get_slot_error_message_notifier(0)); + adaptors[i]->get_message_interface_collection().set_slot_time_message_notifier( + du_list[i]->get_slot_time_message_notifier(0)); + } +} + +void split6_du_impl::start() +{ + for (auto& du_obj : du_list) { + du_obj->start(); + } + + for (auto& adaptor : adaptors) { + adaptor->get_power_operation_controller().start(); + } +} + +void split6_du_impl::stop() +{ + for (auto& du_obj : du_list) { + du_obj->stop(); + } + + for (auto& adaptor : adaptors) { + adaptor->get_power_operation_controller().stop(); + } +} diff --git a/apps/units/flexible_du/split_6/split6_du_impl.h b/apps/units/flexible_du/split_6/split6_du_impl.h new file mode 100644 index 0000000000..ae26d99a3c --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_impl.h @@ -0,0 +1,40 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/du/du.h" +#include "srsran/du/du_high_wrapper.h" +#include "srsran/fapi_adaptor/fapi_adaptor.h" +#include +#include + +namespace srsran { + +class radio_unit; + +class split6_du_impl : public du +{ +public: + explicit split6_du_impl(std::vector> adaptors_, + std::vector> du_list_); + + // See interface for documentation. + void start() override; + + // See interface for documentation. + void stop() override; + +private: + std::vector> du_list; + std::vector> adaptors; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.cpp b/apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.cpp new file mode 100644 index 0000000000..2a9e4d7932 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.cpp @@ -0,0 +1,27 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split6_du_unit_cli11_schema.h" +#include "apps/units/flexible_du/du_high/du_high_config_cli11_schema.h" +#include "apps/units/flexible_du/fapi/fapi_config_cli11_schema.h" +#include "split6_du_unit_config.h" + +using namespace srsran; + +void srsran::configure_cli11_with_split6_du_unit_config_schema(CLI::App& app, split6_du_unit_config& config) +{ + configure_cli11_with_du_high_config_schema(app, config.du_high_cfg); + configure_cli11_with_fapi_config_schema(app, config.fapi_cfg); +} + +void srsran::autoderive_split6_du_parameters_after_parsing(CLI::App& app, split6_du_unit_config& config) +{ + autoderive_du_high_parameters_after_parsing(app, config.du_high_cfg.config); +} diff --git a/apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.h b/apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.h new file mode 100644 index 0000000000..8c86a3ffec --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_unit_cli11_schema.h @@ -0,0 +1,25 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "CLI/CLI11.hpp" + +namespace srsran { + +struct split6_du_unit_config; + +/// Configures the given CLI11 application with the DU Split 6 unit configuration schema. +void configure_cli11_with_split6_du_unit_config_schema(CLI::App& app, split6_du_unit_config& config); + +/// Auto derive DU Split 6 parameters after the parsing. +void autoderive_split6_du_parameters_after_parsing(CLI::App& app, split6_du_unit_config& config); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/split6_du_unit_config.h b/apps/units/flexible_du/split_6/split6_du_unit_config.h new file mode 100644 index 0000000000..fed6d2b368 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_unit_config.h @@ -0,0 +1,26 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_high/du_high_config.h" +#include "apps/units/flexible_du/fapi/fapi_config.h" + +namespace srsran { + +/// DU Split 6 unit configuration. +struct split6_du_unit_config { + /// DU high configuration. + du_high_parsed_config du_high_cfg; + /// FAPI configuration. + fapi_unit_config fapi_cfg; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/split6_du_unit_config_validator.cpp b/apps/units/flexible_du/split_6/split6_du_unit_config_validator.cpp new file mode 100644 index 0000000000..52a4661e55 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_unit_config_validator.cpp @@ -0,0 +1,24 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split6_du_unit_config_validator.h" +#include "apps/units/flexible_du/du_high/du_high_config_validator.h" + +using namespace srsran; + +bool srsran::validate_split6_du_unit_config(const split6_du_unit_config& config, + const os_sched_affinity_bitmask& available_cpus) +{ + if (!validate_du_high_config(config.du_high_cfg.config, available_cpus)) { + return false; + } + + return true; +} diff --git a/apps/units/flexible_du/split_6/split6_du_unit_config_validator.h b/apps/units/flexible_du/split_6/split6_du_unit_config_validator.h new file mode 100644 index 0000000000..fbe8c5c032 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_du_unit_config_validator.h @@ -0,0 +1,21 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "split6_du_unit_config.h" + +namespace srsran { + +/// Validates the given DU Split 6 unit configuration. Returns true on success, false otherwise. +bool validate_split6_du_unit_config(const split6_du_unit_config& config, + const os_sched_affinity_bitmask& available_cpus); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/logger_registrator.h b/apps/units/flexible_du/split_6/split6_du_unit_logger_registrator.h similarity index 51% rename from apps/units/flexible_du/split_6/logger_registrator.h rename to apps/units/flexible_du/split_6/split6_du_unit_logger_registrator.h index ff0e689910..ef681ecc4f 100644 --- a/apps/units/flexible_du/split_6/logger_registrator.h +++ b/apps/units/flexible_du/split_6/split6_du_unit_logger_registrator.h @@ -11,22 +11,16 @@ #pragma once #include "apps/units/flexible_du/du_high/du_high_logger_registrator.h" -#include "apps/units/flexible_du/du_low//du_low_wrapper_config_helper.h.h" #include "apps/units/flexible_du/fapi/fapi_logger_registrator.h" +#include "split6_du_unit_config.h" namespace srsran { -namespace modules { -namespace flexible_du { -namespace split_6 { -/// Registers the DU split 6 loggers in the logger service. -inline void register_logs(const log_appconfig& log_cfg) +/// Registers all the loggers for the DU split 6. +inline void register_split6_du_loggers(const split6_du_unit_config& config) { - du_high::register_logs(log_cfg); - fapi::register_logs(log_cfg); + register_du_high_loggers(config.du_high_cfg.config.loggers); + register_fapi_loggers(config.fapi_cfg); } -} // namespace split_6 -} // namespace flexible_du -} // namespace modules } // namespace srsran diff --git a/apps/units/flexible_du/split_6/split6_plugin.h b/apps/units/flexible_du/split_6/split6_plugin.h new file mode 100644 index 0000000000..354ca87836 --- /dev/null +++ b/apps/units/flexible_du/split_6/split6_plugin.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/fapi_adaptor/fapi_adaptor.h" +#include + +namespace CLI { +class App; +} // namespace CLI + +namespace srsran { + +/// \brief Split 6 plugin interface. +/// +/// The plugin interface allows different implementations of the split 6. +class split6_plugin +{ +public: + virtual ~split6_plugin() = default; + + /// Registers the parsing configuration properties that will be used by this application unit. + virtual void on_parsing_configuration_registration(CLI::App& app) = 0; + + /// Validates the configuration of this application unit. Returns true on success, otherwise false. + virtual bool on_configuration_validation() const = 0; + + /// Registers the loggers of this application unit. + virtual void on_loggers_registration() = 0; + + /// Creates and returns a vector of fapi adaptors, each of them representing a cell. + virtual std::vector> + create_fapi_adaptor(const du_unit_dependencies& dependencies) = 0; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_validator.h b/apps/units/flexible_du/split_7_2/ru_ofh_config_validator.h index 8146fbad43..91985b560a 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_config_validator.h +++ b/apps/units/flexible_du/split_7_2/ru_ofh_config_validator.h @@ -10,7 +10,7 @@ #pragma once -#include "../../../services/os_sched_affinity_manager.h" +#include "apps/services/os_sched_affinity_manager.h" #include "ru_ofh_config.h" #include "srsran/ran/subcarrier_spacing.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp index 8d19295c9a..cda1d39190 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp @@ -136,17 +136,7 @@ static void update_du_metrics(std::vector& flexibl } } -du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, - worker_manager& workers, - srs_du::f1c_connection_client& f1c_client_handler, - srs_du::f1u_du_gateway& f1u_gw, - timer_manager& timer_mng, - mac_pcap& mac_p, - rlc_pcap& rlc_p, - e2_connection_client& e2_client_handler, - e2_metric_connector_manager& e2_metric_connectors, - srslog::sink& json_sink, - app_services::metrics_notifier& metrics_notifier) +du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_dependencies& dependencies) { du_unit du_cmd_wrapper; @@ -256,22 +246,22 @@ du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, span(&max_pusch_per_slot[i], 1), du_impl->get_upper_ru_dl_rg_adapter(), du_impl->get_upper_ru_ul_request_adapter(), - workers, + *dependencies.workers, i); auto cell_services_cfg = fill_du_high_wrapper_config(du_cfg.du_high_cfg, tmp_cfg, i, - workers.get_du_high_executor_mapper(i), - f1c_client_handler, - f1u_gw, - timer_mng, - mac_p, - rlc_p, - e2_client_handler, - e2_metric_connectors, - json_sink, - metrics_notifier); + dependencies.workers->get_du_high_executor_mapper(i), + *dependencies.f1c_client_handler, + *dependencies.f1u_gw, + *dependencies.timer_mng, + *dependencies.mac_p, + *dependencies.rlc_p, + *dependencies.e2_client_handler, + *dependencies.e2_metric_connectors, + *dependencies.json_sink, + *dependencies.metrics_notifier); update_du_metrics(du_cmd_wrapper.metrics, std::move(cell_services_cfg.first), tmp_cfg.e2_cfg.enable_du_e2); @@ -286,9 +276,9 @@ du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, if (fapi_cfg.l2_nof_slots_ahead != 0) { // As the temporal configuration contains only one cell, pick the data from that cell. du_cfg.du_high_cfg.fapi.l2_nof_slots_ahead = fapi_cfg.l2_nof_slots_ahead; - du_cfg.du_high_cfg.fapi.executor.emplace(workers.fapi_exec[i]); + du_cfg.du_high_cfg.fapi.executor.emplace(dependencies.workers->fapi_exec[i]); } else { - report_error_if_not(workers.fapi_exec[i] == nullptr, + report_error_if_not(dependencies.workers->fapi_exec[i] == nullptr, "FAPI buffered worker created for a cell with no MAC delay configured"); } @@ -297,7 +287,7 @@ du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, } std::unique_ptr ru = create_radio_unit(dyn_du_cfg.ru_cfg, - workers, + *dependencies.workers, du_cells, du_impl->get_upper_ru_ul_adapter(), du_impl->get_upper_ru_timing_adapter(), diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h index 2460ba701b..8741931064 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h @@ -10,12 +10,8 @@ #pragma once -#include "apps/gnb/gnb_appconfig.h" -#include "apps/services/application_command.h" -#include "apps/services/metrics/metrics_config.h" #include "apps/services/worker_manager.h" -#include "srsran/du/du.h" -#include "srsran/pcap/rlc_pcap.h" +#include "apps/units/flexible_du/du_unit.h" namespace srsran { @@ -40,23 +36,6 @@ class f1c_connection_client; class f1u_du_gateway; } // namespace srs_du -/// Wraps the DU and its supported application commands. -struct du_unit { - std::unique_ptr unit; - std::vector> commands; - std::vector metrics; -}; - -du_unit create_du(const dynamic_du_unit_config& dyn_du_cfg, - worker_manager& workers, - srs_du::f1c_connection_client& f1c_client_handler, - srs_du::f1u_du_gateway& f1u_gw, - timer_manager& timer_mng, - mac_pcap& mac_p, - rlc_pcap& rlc_p, - e2_connection_client& e2_client_handler, - e2_metric_connector_manager& e2_metric_connectors, - srslog::sink& json_sink, - app_services::metrics_notifier& metrics_notifier); +du_unit create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_dependencies& dependencies); } // namespace srsran diff --git a/include/srsran/fapi_adaptor/fapi_adaptor.h b/include/srsran/fapi_adaptor/fapi_adaptor.h new file mode 100644 index 0000000000..153661b161 --- /dev/null +++ b/include/srsran/fapi_adaptor/fapi_adaptor.h @@ -0,0 +1,76 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +namespace srsran { +namespace fapi { + +class slot_data_message_notifier; +class slot_error_message_notifier; +class slot_last_message_notifier; +class slot_message_gateway; +class slot_time_message_notifier; + +/// \brief FAPI message interface collection interface. +/// +/// This interface gives access to the FAPI message interfaces. +class fapi_message_interface_collection +{ +public: + virtual ~fapi_message_interface_collection() = default; + + /// Returns the slot message gateway of this adaptor. + virtual slot_message_gateway& get_slot_message_gateway() = 0; + + /// Returns the last message notifier of this adaptor. + virtual slot_last_message_notifier& get_slot_last_message_notifier() = 0; + + /// Sets the slot time message notifier to the given notifier. + virtual void set_slot_time_message_notifier(slot_time_message_notifier& notifier_) = 0; + + /// Sets the slot data message notifier to the given notifier. + virtual void set_slot_data_message_notifier(slot_data_message_notifier& notifier_) = 0; + + /// Sets the error message notifier to the given notifier. + virtual void set_slot_error_message_notifier(slot_error_message_notifier& notifier_) = 0; +}; + +/// FAPI power operation controller interface. +class fapi_power_operation_controller +{ +public: + virtual ~fapi_power_operation_controller() = default; + + /// Starts the underlying PHY. Returns true on success, false otherwise. + virtual bool start() = 0; + + /// Stops the underlying PHY. Returns true on success, false otherwise. + virtual bool stop() = 0; +}; + +/// \brief FAPI adaptor interface. +/// +/// The FAPI adaptor provides the functionality to connect to a FAPI interface and interact with it using the +/// controllers provided. +class fapi_adaptor +{ +public: + virtual ~fapi_adaptor() = default; + + /// Returns the power operation controller of this FAPI adaptor. + virtual fapi_power_operation_controller& get_power_operation_controller(); + + /// Returns the message interface collection of this FAPI adaptor. + virtual fapi_message_interface_collection& get_message_interface_collection(); +}; + +} // namespace fapi +} // namespace srsran diff --git a/lib/du/du_wrapper_factory.cpp b/lib/du/du_wrapper_factory.cpp index 78dc8efc54..b6d14f4f0f 100644 --- a/lib/du/du_wrapper_factory.cpp +++ b/lib/du/du_wrapper_factory.cpp @@ -31,7 +31,7 @@ std::unique_ptr srsran::make_du_wrapper(const du_wrapper_config& du_ dependencies.du_hi = make_du_high_wrapper(du_cfg.du_high_cfg, std::move(high_wrapper_dependencies)); - for (unsigned i = 0, e = du_cfg.du_low_cfg.prach_ports.size(); i != e; ++i) { + for (unsigned i = 0, e = du_cfg.du_low_cfg.du_low_cfg.cells.size(); i != e; ++i) { dependencies.du_lo->set_slot_time_message_notifier(i, dependencies.du_hi->get_slot_time_message_notifier(i)); dependencies.du_lo->set_slot_error_message_notifier(i, dependencies.du_hi->get_slot_error_message_notifier(i)); dependencies.du_lo->set_slot_data_message_notifier(i, dependencies.du_hi->get_slot_data_message_notifier(i)); From 4e15ef0e7e118f779b1ef399d2e5198ad21a135e Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 6 Sep 2024 15:57:43 +0200 Subject: [PATCH 005/174] Re-organise DU directories and overhaul dependencies --- apps/gnb/gnb_appconfig_translators.h | 4 +- apps/services/worker_manager.cpp | 2 +- apps/services/worker_manager.h | 2 +- apps/units/cu_cp/cu_cp_builder.cpp | 1 - .../du_high/du_high_config_translators.cpp | 2 +- .../du_high/du_high_config_translators.h | 4 +- .../du_high/du_high_wrapper_config_helper.cpp | 26 +++--- .../du_low/du_low_config_translator.h | 2 +- .../du_low/du_low_wrapper_config_helper.cpp | 2 +- .../du_low/du_low_wrapper_config_helper.h | 2 +- .../split_dynamic/dynamic_du_impl.cpp | 6 +- docs/CMakeLists.txt | 2 +- .../srsran}/asn1/asn1_diff_utils.h | 0 include/srsran/du/du_cell_config.h | 2 +- include/srsran/du/du_cell_config_helpers.h | 6 +- include/srsran/{ => du}/du_high/du_high.h | 0 .../{ => du}/du_high/du_high_configuration.h | 10 +-- .../du_high/du_high_executor_mapper.h | 0 .../srsran/{ => du}/du_high/du_high_factory.h | 4 +- .../srsran/du/{ => du_high}/du_high_wrapper.h | 0 .../du/{ => du_high}/du_high_wrapper_config.h | 2 +- .../{ => du_high}/du_high_wrapper_factory.h | 4 +- .../du_high}/du_manager/du_configurator.h | 0 .../{ => du/du_high}/du_manager/du_manager.h | 2 +- .../du_high}/du_manager/du_manager_factory.h | 4 +- .../du_high}/du_manager/du_manager_params.h | 8 +- .../srsran/du/{ => du_high}/du_qos_config.h | 0 .../du/{ => du_high}/du_qos_config_helpers.h | 2 +- .../srsran/du/{ => du_high}/du_srb_config.h | 0 .../du_test_mode_config.h} | 13 +-- include/srsran/{ => du}/du_low/du_low.h | 0 .../srsran/{ => du}/du_low/du_low_config.h | 0 .../srsran/{ => du}/du_low/du_low_factory.h | 2 +- .../srsran/{ => du}/du_low/du_low_wrapper.h | 0 .../{ => du}/du_low/du_low_wrapper_config.h | 4 +- .../{ => du}/du_low/du_low_wrapper_factory.h | 2 +- include/srsran/du/du_wrapper_config.h | 4 +- include/srsran/e2/e2_factory.h | 2 +- include/srsran/mac/mac_config.h | 4 +- include/srsran/mac/mac_factory.h | 2 +- lib/CMakeLists.txt | 7 +- lib/du/CMakeLists.txt | 20 ++--- lib/du/adapters/fapi_factory.cpp | 89 ------------------- lib/du/adapters/fapi_factory.h | 50 ----------- lib/du/du_cell_config_validation.cpp | 2 +- lib/du/du_high/CMakeLists.txt | 20 +++++ lib/du/du_high/adapters/CMakeLists.txt | 12 +++ lib/{ => du}/du_high/adapters/adapters.h | 2 +- .../adapters/du_high_adapter_factories.h | 7 +- lib/{ => du}/du_high/adapters/f1ap_adapters.h | 2 +- .../adapters/f1ap_test_mode_adapter.cpp | 16 ++-- .../du_high/adapters/f1ap_test_mode_adapter.h | 8 +- .../adapters/mac_test_mode_adapter.cpp | 25 +++--- .../du_high/adapters/mac_test_mode_adapter.h | 40 ++++----- .../du_high/du_high_executor_strategies.h | 2 +- lib/{ => du}/du_high/du_high_factory.cpp | 4 +- lib/{ => du}/du_high/du_high_impl.cpp | 2 +- lib/{ => du}/du_high/du_high_impl.h | 6 +- .../{ => du_high}/du_high_wrapper_factory.cpp | 35 +++++++- lib/du/{ => du_high}/du_high_wrapper_impl.cpp | 0 lib/du/{ => du_high}/du_high_wrapper_impl.h | 4 +- lib/du/du_high/du_manager/CMakeLists.txt | 28 ++++++ .../du_manager/converters/CMakeLists.txt | 5 +- .../asn1_csi_meas_config_helpers.cpp | 2 +- .../converters/asn1_csi_meas_config_helpers.h | 0 .../converters/asn1_rrc_config_helpers.cpp | 2 +- .../converters/asn1_rrc_config_helpers.h | 0 .../converters/f1ap_configuration_helpers.cpp | 0 .../converters/f1ap_configuration_helpers.h | 2 +- .../converters/rlc_config_helpers.cpp | 0 .../converters/rlc_config_helpers.h | 2 +- .../scheduler_configuration_helpers.cpp | 0 .../scheduler_configuration_helpers.h | 0 .../du_high}/du_manager/du_cell_manager.cpp | 0 .../du_high}/du_manager/du_cell_manager.h | 2 +- .../du_manager/du_manager_factory.cpp | 2 +- .../du_high}/du_manager/du_manager_impl.cpp | 0 .../du_high}/du_manager/du_manager_impl.h | 4 +- .../du_high}/du_manager/du_ue/CMakeLists.txt | 4 +- .../du_high}/du_manager/du_ue/du_bearer.cpp | 2 +- .../du_high}/du_manager/du_ue/du_bearer.h | 0 lib/{ => du/du_high}/du_manager/du_ue/du_ue.h | 0 .../du_manager/du_ue/du_ue_adapters.cpp | 0 .../du_manager/du_ue/du_ue_adapters.h | 0 .../du_manager/du_ue/du_ue_bearer_manager.cpp | 0 .../du_manager/du_ue/du_ue_bearer_manager.h | 0 .../du_ue/du_ue_controller_impl.cpp | 0 .../du_manager/du_ue/du_ue_controller_impl.h | 0 .../du_manager/du_ue/du_ue_manager.cpp | 0 .../du_high}/du_manager/du_ue/du_ue_manager.h | 4 +- .../du_ue/du_ue_manager_repository.h | 0 .../du_manager/procedures/CMakeLists.txt | 8 +- .../procedures/du_stop_procedure.cpp | 0 .../du_manager/procedures/du_stop_procedure.h | 4 +- .../du_ue_ric_configuration_procedure.cpp | 0 .../du_ue_ric_configuration_procedure.h | 4 +- .../procedures/initial_du_setup_procedure.cpp | 0 .../procedures/initial_du_setup_procedure.h | 0 .../du_manager/procedures/procedure_logger.h | 0 .../procedures/ue_configuration_procedure.cpp | 0 .../procedures/ue_configuration_procedure.h | 2 +- .../procedures/ue_creation_procedure.cpp | 0 .../procedures/ue_creation_procedure.h | 2 +- .../procedures/ue_deletion_procedure.cpp | 0 .../procedures/ue_deletion_procedure.h | 4 +- .../ran_resource_management/CMakeLists.txt | 4 +- .../du_bearer_resource_manager.cpp | 0 .../du_bearer_resource_manager.h | 0 .../du_pucch_resource_manager.cpp | 0 .../du_pucch_resource_manager.h | 0 .../du_ran_resource_manager.h | 0 .../du_ran_resource_manager_impl.cpp | 0 .../du_ran_resource_manager_impl.h | 0 .../du_ue_resource_config.h | 0 .../pucch_resource_generator.cpp | 0 .../pucch_resource_generator.h | 0 .../ue_capability_manager.cpp | 0 .../ue_capability_manager.h | 0 lib/{ => du}/du_low/CMakeLists.txt | 0 lib/{ => du}/du_low/du_low_factory.cpp | 4 +- lib/{ => du}/du_low/du_low_impl.cpp | 0 lib/{ => du}/du_low/du_low_impl.h | 2 +- .../du_low/du_low_wrapper_factory.cpp | 6 +- lib/{ => du}/du_low/du_low_wrapper_impl.cpp | 0 lib/{ => du}/du_low/du_low_wrapper_impl.h | 4 +- lib/du/du_update_config_helpers.cpp | 2 +- lib/du/du_wrapper_factory.cpp | 4 +- lib/du/du_wrapper_impl.cpp | 4 +- lib/du/du_wrapper_impl.h | 4 +- lib/du_high/CMakeLists.txt | 14 --- lib/du_manager/CMakeLists.txt | 29 ------ lib/e2/common/e2_entity.h | 2 +- .../e2sm_rc_control_action_du_executor.cpp | 1 + .../e2sm_rc_control_action_du_executor.h | 2 +- lib/f1ap/du/f1ap_du_context.h | 2 +- lib/f1ap/du/f1ap_du_factory.cpp | 2 +- lib/f1ap/du/f1ap_du_impl.h | 2 +- lib/f1ap/du/ue_context/f1ap_du_ue_manager.h | 4 +- lib/mac/mac_ctrl/mac_config.h | 4 +- lib/mac/mac_dl/mac_dl_ue_repository.h | 2 +- lib/mac/mac_factory.cpp | 2 +- lib/mac/mac_sched/uci_cell_decoder.h | 2 +- lib/mac/mac_ul/mac_ul_processor.h | 2 +- lib/mac/mac_ul/mac_ul_ue_manager.h | 2 +- lib/mac/mac_ul/pdu_rx_handler.h | 4 +- lib/mac/rnti_manager.h | 2 +- .../du_high => lib/mac}/rnti_value_table.h | 33 ++++--- .../config/sched_cell_config_helpers.cpp | 2 +- .../benchmarks/du_high/du_high_benchmark.cpp | 8 +- .../scheduler_multi_ue_benchmark.cpp | 2 +- .../du_high/mac_test_mode_adapter_test.cpp | 6 +- .../test_utils/du_high_env_simulator.cpp | 4 +- .../test_utils/du_high_env_simulator.h | 4 +- .../test_utils/du_high_worker_manager.h | 2 +- .../du_high_cu/cu_du_test.cpp | 4 +- .../du_high_cu/du_high_cu_test_simulator.cpp | 4 +- .../du_high_cu/du_high_cu_test_simulator.h | 4 +- .../scheduler/pucch_res_test_builder_helper.h | 2 +- .../du_manager/du_manager_test_helpers.cpp | 2 +- .../du_manager/du_manager_test_helpers.h | 4 +- .../du_ran_resource_manager_test.cpp | 4 +- .../du_manager/du_ue/du_bearer_test.cpp | 4 +- .../du_manager/du_ue/ue_manager_test.cpp | 2 +- .../mac_cell_group_config_converter_test.cpp | 2 +- .../du_manager_procedure_test_helpers.cpp | 4 +- .../du_manager_procedure_test_helpers.h | 4 +- ...du_ue_ric_configuration_procedure_test.cpp | 2 +- .../procedures/ue_configuration_test.cpp | 2 +- .../procedures/ue_creation_test.cpp | 2 +- .../procedures/ue_deletion_test.cpp | 4 +- .../pucch_resource_generator_test.cpp | 2 +- .../serving_cell_config_converter_test.cpp | 2 +- tests/unittests/du_manager/sib_test.cpp | 2 +- .../unittests/f1ap/du/f1ap_du_test_helpers.h | 2 +- tests/unittests/mac/mac_ctrl_test_dummies.h | 2 +- .../scheduler/test_utils/config_generators.h | 2 +- .../uci_and_pucch/pucch_res_manager_test.cpp | 2 +- 177 files changed, 359 insertions(+), 446 deletions(-) rename {lib => include/srsran}/asn1/asn1_diff_utils.h (100%) rename include/srsran/{ => du}/du_high/du_high.h (100%) rename include/srsran/{ => du}/du_high/du_high_configuration.h (89%) rename include/srsran/{ => du}/du_high/du_high_executor_mapper.h (100%) rename include/srsran/{ => du}/du_high/du_high_factory.h (82%) rename include/srsran/du/{ => du_high}/du_high_wrapper.h (100%) rename include/srsran/du/{ => du_high}/du_high_wrapper_config.h (96%) rename include/srsran/du/{ => du_high}/du_high_wrapper_factory.h (85%) rename include/srsran/{ => du/du_high}/du_manager/du_configurator.h (100%) rename include/srsran/{ => du/du_high}/du_manager/du_manager.h (98%) rename include/srsran/{ => du/du_high}/du_manager/du_manager_factory.h (80%) rename include/srsran/{ => du/du_high}/du_manager/du_manager_params.h (91%) rename include/srsran/du/{ => du_high}/du_qos_config.h (100%) rename include/srsran/du/{ => du_high}/du_qos_config_helpers.h (99%) rename include/srsran/du/{ => du_high}/du_srb_config.h (100%) rename include/srsran/du/{du_test_config.h => du_high/du_test_mode_config.h} (73%) rename include/srsran/{ => du}/du_low/du_low.h (100%) rename include/srsran/{ => du}/du_low/du_low_config.h (100%) rename include/srsran/{ => du}/du_low/du_low_factory.h (92%) rename include/srsran/{ => du}/du_low/du_low_wrapper.h (100%) rename include/srsran/{ => du}/du_low/du_low_wrapper_config.h (88%) rename include/srsran/{ => du}/du_low/du_low_wrapper_factory.h (93%) delete mode 100644 lib/du/adapters/fapi_factory.cpp delete mode 100644 lib/du/adapters/fapi_factory.h create mode 100644 lib/du/du_high/CMakeLists.txt create mode 100644 lib/du/du_high/adapters/CMakeLists.txt rename lib/{ => du}/du_high/adapters/adapters.h (95%) rename lib/{ => du}/du_high/adapters/du_high_adapter_factories.h (71%) rename lib/{ => du}/du_high/adapters/f1ap_adapters.h (98%) rename lib/{ => du}/du_high/adapters/f1ap_test_mode_adapter.cpp (94%) rename lib/{ => du}/du_high/adapters/f1ap_test_mode_adapter.h (80%) rename lib/{ => du}/du_high/adapters/mac_test_mode_adapter.cpp (95%) rename lib/{ => du}/du_high/adapters/mac_test_mode_adapter.h (87%) rename lib/{ => du}/du_high/du_high_executor_strategies.h (99%) rename lib/{ => du}/du_high/du_high_factory.cpp (89%) rename lib/{ => du}/du_high/du_high_impl.cpp (99%) rename lib/{ => du}/du_high/du_high_impl.h (92%) rename lib/du/{ => du_high}/du_high_wrapper_factory.cpp (88%) rename lib/du/{ => du_high}/du_high_wrapper_impl.cpp (100%) rename lib/du/{ => du_high}/du_high_wrapper_impl.h (95%) create mode 100644 lib/du/du_high/du_manager/CMakeLists.txt rename lib/{ => du/du_high}/du_manager/converters/CMakeLists.txt (90%) rename lib/{ => du/du_high}/du_manager/converters/asn1_csi_meas_config_helpers.cpp (99%) rename lib/{ => du/du_high}/du_manager/converters/asn1_csi_meas_config_helpers.h (100%) rename lib/{ => du/du_high}/du_manager/converters/asn1_rrc_config_helpers.cpp (99%) rename lib/{ => du/du_high}/du_manager/converters/asn1_rrc_config_helpers.h (100%) rename lib/{ => du/du_high}/du_manager/converters/f1ap_configuration_helpers.cpp (100%) rename lib/{ => du/du_high}/du_manager/converters/f1ap_configuration_helpers.h (97%) rename lib/{ => du/du_high}/du_manager/converters/rlc_config_helpers.cpp (100%) rename lib/{ => du/du_high}/du_manager/converters/rlc_config_helpers.h (97%) rename lib/{ => du/du_high}/du_manager/converters/scheduler_configuration_helpers.cpp (100%) rename lib/{ => du/du_high}/du_manager/converters/scheduler_configuration_helpers.h (100%) rename lib/{ => du/du_high}/du_manager/du_cell_manager.cpp (100%) rename lib/{ => du/du_high}/du_manager/du_cell_manager.h (96%) rename lib/{ => du/du_high}/du_manager/du_manager_factory.cpp (89%) rename lib/{ => du/du_high}/du_manager/du_manager_impl.cpp (100%) rename lib/{ => du/du_high}/du_manager/du_manager_impl.h (95%) rename lib/{ => du/du_high}/du_manager/du_ue/CMakeLists.txt (53%) rename lib/{ => du/du_high}/du_manager/du_ue/du_bearer.cpp (99%) rename lib/{ => du/du_high}/du_manager/du_ue/du_bearer.h (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue.h (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_adapters.cpp (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_adapters.h (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_bearer_manager.cpp (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_bearer_manager.h (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_controller_impl.cpp (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_controller_impl.h (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_manager.cpp (100%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_manager.h (97%) rename lib/{ => du/du_high}/du_manager/du_ue/du_ue_manager_repository.h (100%) rename lib/{ => du/du_high}/du_manager/procedures/CMakeLists.txt (86%) rename lib/{ => du/du_high}/du_manager/procedures/du_stop_procedure.cpp (100%) rename lib/{ => du/du_high}/du_manager/procedures/du_stop_procedure.h (92%) rename lib/{ => du/du_high}/du_manager/procedures/du_ue_ric_configuration_procedure.cpp (100%) rename lib/{ => du/du_high}/du_manager/procedures/du_ue_ric_configuration_procedure.h (94%) rename lib/{ => du/du_high}/du_manager/procedures/initial_du_setup_procedure.cpp (100%) rename lib/{ => du/du_high}/du_manager/procedures/initial_du_setup_procedure.h (100%) rename lib/{ => du/du_high}/du_manager/procedures/procedure_logger.h (100%) rename lib/{ => du/du_high}/du_manager/procedures/ue_configuration_procedure.cpp (100%) rename lib/{ => du/du_high}/du_manager/procedures/ue_configuration_procedure.h (97%) rename lib/{ => du/du_high}/du_manager/procedures/ue_creation_procedure.cpp (100%) rename lib/{ => du/du_high}/du_manager/procedures/ue_creation_procedure.h (98%) rename lib/{ => du/du_high}/du_manager/procedures/ue_deletion_procedure.cpp (100%) rename lib/{ => du/du_high}/du_manager/procedures/ue_deletion_procedure.h (91%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/CMakeLists.txt (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_bearer_resource_manager.cpp (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_bearer_resource_manager.h (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_pucch_resource_manager.cpp (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_pucch_resource_manager.h (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_ran_resource_manager.h (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_ran_resource_manager_impl.h (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/du_ue_resource_config.h (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/pucch_resource_generator.cpp (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/pucch_resource_generator.h (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/ue_capability_manager.cpp (100%) rename lib/{ => du/du_high}/du_manager/ran_resource_management/ue_capability_manager.h (100%) rename lib/{ => du}/du_low/CMakeLists.txt (100%) rename lib/{ => du}/du_low/du_low_factory.cpp (96%) rename lib/{ => du}/du_low/du_low_impl.cpp (100%) rename lib/{ => du}/du_low/du_low_impl.h (95%) rename lib/{ => du}/du_low/du_low_wrapper_factory.cpp (97%) rename lib/{ => du}/du_low/du_low_wrapper_impl.cpp (100%) rename lib/{ => du}/du_low/du_low_wrapper_impl.h (95%) delete mode 100644 lib/du_high/CMakeLists.txt delete mode 100644 lib/du_manager/CMakeLists.txt rename {include/srsran/du_high => lib/mac}/rnti_value_table.h (79%) diff --git a/apps/gnb/gnb_appconfig_translators.h b/apps/gnb/gnb_appconfig_translators.h index e7e7bca56e..6831aa7fec 100644 --- a/apps/gnb/gnb_appconfig_translators.h +++ b/apps/gnb/gnb_appconfig_translators.h @@ -13,8 +13,8 @@ #include "srsran/cu_cp/cu_cp_configuration.h" #include "srsran/cu_up/cu_up_configuration.h" #include "srsran/du/du_cell_config.h" -#include "srsran/du/du_qos_config.h" -#include "srsran/du/du_srb_config.h" +#include "srsran/du/du_high/du_qos_config.h" +#include "srsran/du/du_high/du_srb_config.h" #include "srsran/e2/e2ap_configuration.h" #include "srsran/gateways/sctp_network_gateway.h" #include "srsran/mac/mac_config.h" diff --git a/apps/services/worker_manager.cpp b/apps/services/worker_manager.cpp index dda928764b..b112a7d943 100644 --- a/apps/services/worker_manager.cpp +++ b/apps/services/worker_manager.cpp @@ -9,7 +9,7 @@ */ #include "worker_manager.h" -#include "../../lib/du_high/du_high_executor_strategies.h" +#include "../../lib/du/du_high/du_high_executor_strategies.h" #include "srsran/ran/pdsch/pdsch_constants.h" #include "srsran/support/event_tracing.h" diff --git a/apps/services/worker_manager.h b/apps/services/worker_manager.h index 809f72d8fe..f183c67d2f 100644 --- a/apps/services/worker_manager.h +++ b/apps/services/worker_manager.h @@ -17,7 +17,7 @@ #include "apps/units/cu_up/cu_up_unit_pcap_config.h" #include "os_sched_affinity_manager.h" #include "srsran/cu_up/cu_up_executor_pool.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/support/executors/task_execution_manager.h" #include "srsran/support/executors/task_executor.h" diff --git a/apps/units/cu_cp/cu_cp_builder.cpp b/apps/units/cu_cp/cu_cp_builder.cpp index 1c47f50a69..a499d42b4b 100644 --- a/apps/units/cu_cp/cu_cp_builder.cpp +++ b/apps/units/cu_cp/cu_cp_builder.cpp @@ -9,7 +9,6 @@ */ #include "cu_cp_builder.h" -#include "apps/services/worker_manager.h" #include "cu_cp_commands.h" #include "cu_cp_config_translators.h" #include "srsran/cu_cp/cu_cp_factory.h" diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index 55acfc3f23..25eba276f6 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -12,7 +12,7 @@ #include "du_high_config.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/du/du_cell_config_validation.h" -#include "srsran/du/du_qos_config_helpers.h" +#include "srsran/du/du_high/du_qos_config_helpers.h" #include "srsran/du/du_update_config_helpers.h" #include "srsran/e2/e2ap_configuration_helpers.h" #include "srsran/ran/duplex_mode.h" diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.h b/apps/units/flexible_du/du_high/du_high_config_translators.h index c9606f10e6..6537dfd94d 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.h +++ b/apps/units/flexible_du/du_high/du_high_config_translators.h @@ -12,8 +12,8 @@ #include "du_high_config.h" #include "srsran/du/du_cell_config.h" -#include "srsran/du/du_qos_config.h" -#include "srsran/du/du_srb_config.h" +#include "srsran/du/du_high/du_qos_config.h" +#include "srsran/du/du_high/du_srb_config.h" #include "srsran/e2/e2ap_configuration.h" #include "srsran/mac/mac_config.h" #include "srsran/ran/lcid.h" diff --git a/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp b/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp index e496477a1e..9919b79745 100644 --- a/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp +++ b/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp @@ -18,7 +18,7 @@ #include "metrics/du_high_rlc_metrics_producer.h" #include "metrics/du_high_scheduler_cell_metrics_consumers.h" #include "metrics/du_high_scheduler_cell_metrics_producer.h" -#include "srsran/du/du_high_wrapper_factory.h" +#include "srsran/du/du_high/du_high_wrapper_factory.h" using namespace srsran; @@ -187,18 +187,18 @@ srsran::fill_du_high_wrapper_config(du_high_wrapper_config& out_cfg, // Configure test mode if (du_high_unit_cfg.test_mode_cfg.test_ue.rnti != rnti_t::INVALID_RNTI) { - du_hi_cfg.test_cfg.test_ue = - srs_du::du_test_config::test_ue_config{du_high_unit_cfg.test_mode_cfg.test_ue.rnti, - du_high_unit_cfg.test_mode_cfg.test_ue.nof_ues, - du_high_unit_cfg.test_mode_cfg.test_ue.auto_ack_indication_delay, - du_high_unit_cfg.test_mode_cfg.test_ue.pdsch_active, - du_high_unit_cfg.test_mode_cfg.test_ue.pusch_active, - du_high_unit_cfg.test_mode_cfg.test_ue.cqi, - du_high_unit_cfg.test_mode_cfg.test_ue.ri, - du_high_unit_cfg.test_mode_cfg.test_ue.pmi, - du_high_unit_cfg.test_mode_cfg.test_ue.i_1_1, - du_high_unit_cfg.test_mode_cfg.test_ue.i_1_3, - du_high_unit_cfg.test_mode_cfg.test_ue.i_2}; + du_hi_cfg.test_cfg.test_ue = srs_du::du_test_mode_config::test_mode_ue_config{ + du_high_unit_cfg.test_mode_cfg.test_ue.rnti, + du_high_unit_cfg.test_mode_cfg.test_ue.nof_ues, + du_high_unit_cfg.test_mode_cfg.test_ue.auto_ack_indication_delay, + du_high_unit_cfg.test_mode_cfg.test_ue.pdsch_active, + du_high_unit_cfg.test_mode_cfg.test_ue.pusch_active, + du_high_unit_cfg.test_mode_cfg.test_ue.cqi, + du_high_unit_cfg.test_mode_cfg.test_ue.ri, + du_high_unit_cfg.test_mode_cfg.test_ue.pmi, + du_high_unit_cfg.test_mode_cfg.test_ue.i_1_1, + du_high_unit_cfg.test_mode_cfg.test_ue.i_1_3, + du_high_unit_cfg.test_mode_cfg.test_ue.i_2}; } return du_services_cfg; diff --git a/apps/units/flexible_du/du_low/du_low_config_translator.h b/apps/units/flexible_du/du_low/du_low_config_translator.h index 27a764252d..650fc24ddb 100644 --- a/apps/units/flexible_du/du_low/du_low_config_translator.h +++ b/apps/units/flexible_du/du_low/du_low_config_translator.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/adt/span.h" -#include "srsran/du_low/du_low_wrapper_config.h" +#include "srsran/du/du_low/du_low_wrapper_config.h" namespace srsran { diff --git a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp index 502b1a1a9a..f745eb159e 100644 --- a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp +++ b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp @@ -11,7 +11,7 @@ #include "du_low_wrapper_config_helper.h" #include "apps/services/worker_manager.h" #include "du_low_config_translator.h" -#include "srsran/du_low/du_low_wrapper_factory.h" +#include "srsran/du/du_low/du_low_wrapper_factory.h" using namespace srsran; diff --git a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h index 0f8944c437..b179385c6b 100644 --- a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h +++ b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/adt/span.h" -#include "srsran/du_low/du_low_wrapper_config.h" +#include "srsran/du/du_low/du_low_wrapper_config.h" namespace srsran { diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp index f643b54927..59bf6e0979 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp @@ -10,9 +10,9 @@ #include "dynamic_du_impl.h" +#include "srsran/du/du_low/du_low.h" +#include "srsran/du/du_low/du_low_wrapper.h" #include "srsran/du/du_wrapper.h" -#include "srsran/du_low/du_low.h" -#include "srsran/du_low/du_low_wrapper.h" #include "srsran/phy/upper/upper_phy.h" #include "srsran/ru/ru.h" #include "srsran/ru/ru_controller.h" @@ -65,4 +65,4 @@ void dynamic_du_impl::add_dus(std::vector> active_du ru_error_adapt.map_handler(upper->get_sector_id(), upper->get_error_handler()); } } -} \ No newline at end of file +} diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 19b648b5d7..1c8818c7cf 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -79,7 +79,7 @@ if (DOXYGEN_FOUND) ${CMAKE_HOME_DIRECTORY}/include/srsran/rlc ${CMAKE_HOME_DIRECTORY}/include/srsran/f1ap/common ${CMAKE_HOME_DIRECTORY}/include/srsran/f1ap/du - ${CMAKE_HOME_DIRECTORY}/include/srsran/du_manager + ${CMAKE_HOME_DIRECTORY}/include/srsran/du/du_manager ${CMAKE_HOME_DIRECTORY}/lib/mac ${CMAKE_HOME_DIRECTORY}/lib/scheduler ${CMAKE_HOME_DIRECTORY}/lib/rlc diff --git a/lib/asn1/asn1_diff_utils.h b/include/srsran/asn1/asn1_diff_utils.h similarity index 100% rename from lib/asn1/asn1_diff_utils.h rename to include/srsran/asn1/asn1_diff_utils.h diff --git a/include/srsran/du/du_cell_config.h b/include/srsran/du/du_cell_config.h index d15c8e4892..7202ec5b05 100644 --- a/include/srsran/du/du_cell_config.h +++ b/include/srsran/du/du_cell_config.h @@ -185,7 +185,7 @@ struct du_cell_config { /// Parameters for SRS-Config generation. srs_builder_params srs_cfg; - /// Defines the maximum allowable channel delay in slots when runnning in NTN mode. seee (TS 38.300 section 16.14.2) + /// Defines the maximum allowable channel delay in slots when runnning in NTN mode. see TS38.300 section 16.14.2. unsigned ntn_cs_koffset = 0; /// List of RAN slices to support in the scheduler. diff --git a/include/srsran/du/du_cell_config_helpers.h b/include/srsran/du/du_cell_config_helpers.h index 73920a0539..1922296b9b 100644 --- a/include/srsran/du/du_cell_config_helpers.h +++ b/include/srsran/du/du_cell_config_helpers.h @@ -10,8 +10,8 @@ #pragma once -#include "du_cell_config.h" -#include "srsran/du/du_qos_config.h" +#include "srsran/du/du_cell_config.h" +#include "srsran/du/du_high/du_qos_config.h" #include "srsran/mac/config/mac_config_helpers.h" #include "srsran/ran/band_helper.h" #include "srsran/ran/pdcch/pdcch_type0_css_coreset_config.h" @@ -22,8 +22,6 @@ #include "srsran/scheduler/config/serving_cell_config_factory.h" #include -// TODO: This file is temporary. Eventually we will receive cell configurations from the DU config file. - namespace srsran { namespace config_helpers { diff --git a/include/srsran/du_high/du_high.h b/include/srsran/du/du_high/du_high.h similarity index 100% rename from include/srsran/du_high/du_high.h rename to include/srsran/du/du_high/du_high.h diff --git a/include/srsran/du_high/du_high_configuration.h b/include/srsran/du/du_high/du_high_configuration.h similarity index 89% rename from include/srsran/du_high/du_high_configuration.h rename to include/srsran/du/du_high/du_high_configuration.h index 8750f09d9d..f08a00fd3b 100644 --- a/include/srsran/du_high/du_high_configuration.h +++ b/include/srsran/du/du_high/du_high_configuration.h @@ -2,10 +2,10 @@ #pragma once #include "srsran/du/du_cell_config.h" -#include "srsran/du/du_qos_config.h" -#include "srsran/du/du_srb_config.h" -#include "srsran/du/du_test_config.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_qos_config.h" +#include "srsran/du/du_high/du_srb_config.h" +#include "srsran/du/du_high/du_test_mode_config.h" #include "srsran/e2/e2.h" #include "srsran/e2/e2_connection_client.h" #include "srsran/e2/e2ap_configuration.h" @@ -54,7 +54,7 @@ struct du_high_configuration { e2_du_metrics_interface* e2_du_metric_iface = nullptr; mac_pcap* mac_p = nullptr; rlc_pcap* rlc_p = nullptr; - du_test_config test_cfg; + du_test_mode_config test_cfg; e2ap_configuration e2ap_config; }; diff --git a/include/srsran/du_high/du_high_executor_mapper.h b/include/srsran/du/du_high/du_high_executor_mapper.h similarity index 100% rename from include/srsran/du_high/du_high_executor_mapper.h rename to include/srsran/du/du_high/du_high_executor_mapper.h diff --git a/include/srsran/du_high/du_high_factory.h b/include/srsran/du/du_high/du_high_factory.h similarity index 82% rename from include/srsran/du_high/du_high_factory.h rename to include/srsran/du/du_high/du_high_factory.h index c6359e1696..9de4ffbdf1 100644 --- a/include/srsran/du_high/du_high_factory.h +++ b/include/srsran/du/du_high/du_high_factory.h @@ -10,8 +10,8 @@ #pragma once -#include "srsran/du_high/du_high.h" -#include "srsran/du_high/du_high_configuration.h" +#include "srsran/du/du_high/du_high.h" +#include "srsran/du/du_high/du_high_configuration.h" namespace srsran { diff --git a/include/srsran/du/du_high_wrapper.h b/include/srsran/du/du_high/du_high_wrapper.h similarity index 100% rename from include/srsran/du/du_high_wrapper.h rename to include/srsran/du/du_high/du_high_wrapper.h diff --git a/include/srsran/du/du_high_wrapper_config.h b/include/srsran/du/du_high/du_high_wrapper_config.h similarity index 96% rename from include/srsran/du/du_high_wrapper_config.h rename to include/srsran/du/du_high/du_high_wrapper_config.h index 172f7a05df..8067f995af 100644 --- a/include/srsran/du/du_high_wrapper_config.h +++ b/include/srsran/du/du_high/du_high_wrapper_config.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_high/du_high_configuration.h" +#include "srsran/du/du_high/du_high_configuration.h" namespace srsran { diff --git a/include/srsran/du/du_high_wrapper_factory.h b/include/srsran/du/du_high/du_high_wrapper_factory.h similarity index 85% rename from include/srsran/du/du_high_wrapper_factory.h rename to include/srsran/du/du_high/du_high_wrapper_factory.h index b4fd76421d..41a2e4af93 100644 --- a/include/srsran/du/du_high_wrapper_factory.h +++ b/include/srsran/du/du_high/du_high_wrapper_factory.h @@ -11,8 +11,8 @@ #pragma once -#include "srsran/du/du_high_wrapper.h" -#include "srsran/du/du_high_wrapper_config.h" +#include "srsran/du/du_high/du_high_wrapper.h" +#include "srsran/du/du_high/du_high_wrapper_config.h" #include namespace srsran { diff --git a/include/srsran/du_manager/du_configurator.h b/include/srsran/du/du_high/du_manager/du_configurator.h similarity index 100% rename from include/srsran/du_manager/du_configurator.h rename to include/srsran/du/du_high/du_manager/du_configurator.h diff --git a/include/srsran/du_manager/du_manager.h b/include/srsran/du/du_high/du_manager/du_manager.h similarity index 98% rename from include/srsran/du_manager/du_manager.h rename to include/srsran/du/du_high/du_manager/du_manager.h index 6e80925012..9cfe6c10dd 100644 --- a/include/srsran/du_manager/du_manager.h +++ b/include/srsran/du/du_high/du_manager/du_manager.h @@ -1,8 +1,8 @@ #pragma once -#include "du_configurator.h" #include "srsran/adt/byte_buffer.h" +#include "srsran/du/du_high/du_manager/du_configurator.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/ran/du_types.h" #include "srsran/ran/lcid.h" diff --git a/include/srsran/du_manager/du_manager_factory.h b/include/srsran/du/du_high/du_manager/du_manager_factory.h similarity index 80% rename from include/srsran/du_manager/du_manager_factory.h rename to include/srsran/du/du_high/du_manager/du_manager_factory.h index dba43d2ef1..08af681489 100644 --- a/include/srsran/du_manager/du_manager_factory.h +++ b/include/srsran/du/du_high/du_manager/du_manager_factory.h @@ -10,8 +10,8 @@ #pragma once -#include "du_manager.h" -#include "du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" namespace srsran { namespace srs_du { diff --git a/include/srsran/du_manager/du_manager_params.h b/include/srsran/du/du_high/du_manager/du_manager_params.h similarity index 91% rename from include/srsran/du_manager/du_manager_params.h rename to include/srsran/du/du_high/du_manager/du_manager_params.h index 3d1987d761..10e1a75be4 100644 --- a/include/srsran/du_manager/du_manager_params.h +++ b/include/srsran/du/du_high/du_manager/du_manager_params.h @@ -11,10 +11,10 @@ #pragma once #include "srsran/du/du_cell_config.h" -#include "srsran/du/du_qos_config.h" -#include "srsran/du/du_srb_config.h" -#include "srsran/du/du_test_config.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_qos_config.h" +#include "srsran/du/du_high/du_srb_config.h" +#include "srsran/du/du_high/du_test_mode_config.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/f1u/du/f1u_gateway.h" #include "srsran/mac/mac.h" diff --git a/include/srsran/du/du_qos_config.h b/include/srsran/du/du_high/du_qos_config.h similarity index 100% rename from include/srsran/du/du_qos_config.h rename to include/srsran/du/du_high/du_qos_config.h diff --git a/include/srsran/du/du_qos_config_helpers.h b/include/srsran/du/du_high/du_qos_config_helpers.h similarity index 99% rename from include/srsran/du/du_qos_config_helpers.h rename to include/srsran/du/du_high/du_qos_config_helpers.h index 8ec28ee87b..0ed6257ec8 100644 --- a/include/srsran/du/du_qos_config_helpers.h +++ b/include/srsran/du/du_high/du_qos_config_helpers.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du/du_qos_config.h" +#include "srsran/du/du_high/du_qos_config.h" #include "srsran/mac/config/mac_config_helpers.h" #include "srsran/ran/qos/five_qi.h" #include diff --git a/include/srsran/du/du_srb_config.h b/include/srsran/du/du_high/du_srb_config.h similarity index 100% rename from include/srsran/du/du_srb_config.h rename to include/srsran/du/du_high/du_srb_config.h diff --git a/include/srsran/du/du_test_config.h b/include/srsran/du/du_high/du_test_mode_config.h similarity index 73% rename from include/srsran/du/du_test_config.h rename to include/srsran/du/du_high/du_test_mode_config.h index 31982dfcf5..9760a76dd5 100644 --- a/include/srsran/du/du_test_config.h +++ b/include/srsran/du/du_high/du_test_mode_config.h @@ -10,14 +10,15 @@ #pragma once -#include "srsran/du/du_cell_config.h" +#include "srsran/ran/rnti.h" +#include namespace srsran { namespace srs_du { -/// \brief Configuration that enable DU modes operation for testing purposes. -struct du_test_config { - struct test_ue_config { +/// Configuration that enable DU test mode operation. +struct du_test_mode_config { + struct test_mode_ue_config { rnti_t rnti; uint16_t nof_ues; std::optional auto_ack_indication_delay; @@ -31,8 +32,8 @@ struct du_test_config { unsigned i_2; }; - /// \brief Creation of a phantom UE for testing purposes. - std::optional test_ue; + /// Creation of a phantom UE for test mode operation. + std::optional test_ue; }; } // namespace srs_du diff --git a/include/srsran/du_low/du_low.h b/include/srsran/du/du_low/du_low.h similarity index 100% rename from include/srsran/du_low/du_low.h rename to include/srsran/du/du_low/du_low.h diff --git a/include/srsran/du_low/du_low_config.h b/include/srsran/du/du_low/du_low_config.h similarity index 100% rename from include/srsran/du_low/du_low_config.h rename to include/srsran/du/du_low/du_low_config.h diff --git a/include/srsran/du_low/du_low_factory.h b/include/srsran/du/du_low/du_low_factory.h similarity index 92% rename from include/srsran/du_low/du_low_factory.h rename to include/srsran/du/du_low/du_low_factory.h index ec36b83252..1af15dbbbd 100644 --- a/include/srsran/du_low/du_low_factory.h +++ b/include/srsran/du/du_low/du_low_factory.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_low/du_low.h" +#include "srsran/du/du_low/du_low.h" #include namespace srsran { diff --git a/include/srsran/du_low/du_low_wrapper.h b/include/srsran/du/du_low/du_low_wrapper.h similarity index 100% rename from include/srsran/du_low/du_low_wrapper.h rename to include/srsran/du/du_low/du_low_wrapper.h diff --git a/include/srsran/du_low/du_low_wrapper_config.h b/include/srsran/du/du_low/du_low_wrapper_config.h similarity index 88% rename from include/srsran/du_low/du_low_wrapper_config.h rename to include/srsran/du/du_low/du_low_wrapper_config.h index eb974ab90e..0f5c533ee3 100644 --- a/include/srsran/du_low/du_low_wrapper_config.h +++ b/include/srsran/du/du_low/du_low_wrapper_config.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_low/du_low_config.h" +#include "srsran/du/du_low/du_low_config.h" namespace srsran { @@ -25,4 +25,4 @@ struct du_low_wrapper_config { std::vector prach_ports; }; -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/include/srsran/du_low/du_low_wrapper_factory.h b/include/srsran/du/du_low/du_low_wrapper_factory.h similarity index 93% rename from include/srsran/du_low/du_low_wrapper_factory.h rename to include/srsran/du/du_low/du_low_wrapper_factory.h index de608ea3fc..1a4121c11f 100644 --- a/include/srsran/du_low/du_low_wrapper_factory.h +++ b/include/srsran/du/du_low/du_low_wrapper_factory.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/adt/span.h" -#include "srsran/du_low/du_low_wrapper.h" +#include "srsran/du/du_low/du_low_wrapper.h" #include diff --git a/include/srsran/du/du_wrapper_config.h b/include/srsran/du/du_wrapper_config.h index a0a44dd9e6..ea3be4719d 100644 --- a/include/srsran/du/du_wrapper_config.h +++ b/include/srsran/du/du_wrapper_config.h @@ -10,8 +10,8 @@ #pragma once -#include "srsran//du_low/du_low_wrapper_config.h" -#include "srsran/du/du_high_wrapper_config.h" +#include "srsran/du/du_high/du_high_wrapper_config.h" +#include "srsran/du/du_low/du_low_wrapper_config.h" namespace srsran { diff --git a/include/srsran/e2/e2_factory.h b/include/srsran/e2/e2_factory.h index eff563f649..1c51ef9d27 100644 --- a/include/srsran/e2/e2_factory.h +++ b/include/srsran/e2/e2_factory.h @@ -15,7 +15,7 @@ #include "e2ap_configuration.h" #include "e2sm/e2sm_manager.h" #include "subscription/e2_subscription.h" -#include "srsran/du_manager/du_configurator.h" +#include "srsran/du/du_high/du_manager/du_configurator.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/gateways/sctp_network_gateway.h" #include "srsran/pcap/dlt_pcap.h" diff --git a/include/srsran/mac/mac_config.h b/include/srsran/mac/mac_config.h index 3030c51d4d..81e3ac678b 100644 --- a/include/srsran/mac/mac_config.h +++ b/include/srsran/mac/mac_config.h @@ -10,8 +10,8 @@ #pragma once -#include "srsran/du/du_test_config.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_test_mode_config.h" #include "srsran/mac/mac_cell_result.h" #include "srsran/mac/mac_pdu_handler.h" #include "srsran/pcap/mac_pcap.h" diff --git a/include/srsran/mac/mac_factory.h b/include/srsran/mac/mac_factory.h index 850c5d5a9a..5790b651df 100644 --- a/include/srsran/mac/mac_factory.h +++ b/include/srsran/mac/mac_factory.h @@ -12,7 +12,7 @@ #include "mac.h" #include "mac_cell_result.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/mac/mac_config.h" #include "srsran/scheduler/config/scheduler_expert_config.h" #include diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index cfc2eda93e..85cddc3dce 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -10,11 +10,6 @@ add_subdirectory(asn1) add_subdirectory(cu_cp) add_subdirectory(cu_up) add_subdirectory(du) -add_subdirectory(du_high) -if (NOT DU_SPLIT_6) - add_subdirectory(du_low) -endif () -add_subdirectory(du_manager) add_subdirectory(e1ap) add_subdirectory(e2) add_subdirectory(f1ap) @@ -23,10 +18,10 @@ add_subdirectory(fapi) add_subdirectory(fapi_adaptor) add_subdirectory(gateways) add_subdirectory(gtpu) -add_subdirectory(instrumentation) if (DPDK_FOUND) add_subdirectory(hal) endif (DPDK_FOUND) +add_subdirectory(instrumentation) add_subdirectory(mac) add_subdirectory(ngap) add_subdirectory(nru) diff --git a/lib/du/CMakeLists.txt b/lib/du/CMakeLists.txt index 2d9f0648e2..6373e660dd 100644 --- a/lib/du/CMakeLists.txt +++ b/lib/du/CMakeLists.txt @@ -6,26 +6,24 @@ # the distribution. # +add_subdirectory(du_high) +if (NOT DU_SPLIT_6) + add_subdirectory(du_low) +endif () + set(SOURCES du_cell_config_validation.cpp du_update_config_helpers.cpp) add_library(srsran_du_config_validators STATIC ${SOURCES}) -add_library(srsran_du_high_wrapper STATIC - du_high_wrapper_factory.cpp - du_high_wrapper_impl.cpp - adapters/fapi_factory.cpp) -target_link_libraries(srsran_du_high_wrapper PUBLIC srsran_du_config_validators srsran_du_high srsran_mac_fapi_adaptor srsran_fapi) - - add_library(srsran_du_wrapper STATIC du_wrapper_impl.cpp du_wrapper_factory.cpp) -set(DU_WRAPPER_LIBRARIES srsran_du_high_wrapper srsran_du_low_wrapper) + +target_link_libraries(srsran_du_wrapper PUBLIC srsran_du_high_wrapper srsran_du_low_wrapper) # Hardware acceleration for both PUSCH and PDSCH is enabled by default when using DPDK. if (DPDK_FOUND) set_source_files_properties(du_wrapper_factory.cpp du_wrapper_impl.cpp PROPERTIES COMPILE_DEFINITIONS "DPDK_FOUND; HWACC_PDSCH_ENABLED; HWACC_PUSCH_ENABLED") list(APPEND DU_LOW_LIBRARIES hal_hwacc_pusch - hal_hwacc_pdsch - hal_bbdev_factory) + hal_hwacc_pdsch + hal_bbdev_factory) endif (DPDK_FOUND) -target_link_libraries(srsran_du_wrapper PUBLIC ${DU_WRAPPER_LIBRARIES}) diff --git a/lib/du/adapters/fapi_factory.cpp b/lib/du/adapters/fapi_factory.cpp deleted file mode 100644 index 3490fd5110..0000000000 --- a/lib/du/adapters/fapi_factory.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright 2021-2024 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#include "fapi_factory.h" -#include "srsran/fapi_adaptor/mac/mac_fapi_adaptor_factory.h" -#include "srsran/srslog/srslog.h" -#include "srsran/support/error_handling.h" -#include - -using namespace srsran; -using namespace fapi_adaptor; - -std::unique_ptr -srsran::build_phy_fapi_adaptor(unsigned sector_id, - unsigned nof_slots_request_headroom, - subcarrier_spacing scs, - subcarrier_spacing scs_common, - downlink_processor_pool& dl_processor_pool, - resource_grid_pool& dl_rg_pool, - uplink_request_processor& ul_request_processor, - resource_grid_pool& ul_rg_pool, - uplink_slot_pdu_repository& ul_pdu_repository, - const downlink_pdu_validator& dl_pdu_validator, - const uplink_pdu_validator& ul_pdu_validator, - const fapi::prach_config& prach_cfg, - const fapi::carrier_config& carrier_cfg, - std::unique_ptr pm_repo, - std::unique_ptr part2_repo, - std::vector prach_ports) -{ - std::unique_ptr adaptor_factory = create_phy_fapi_adaptor_factory(); - report_error_if_not(adaptor_factory, "Invalid PHY adaptor factory."); - - phy_fapi_adaptor_factory_config phy_fapi_config; - phy_fapi_config.sector_id = sector_id; - phy_fapi_config.nof_slots_request_headroom = nof_slots_request_headroom; - phy_fapi_config.scs = scs; - phy_fapi_config.scs_common = scs_common; - phy_fapi_config.prach_cfg = &prach_cfg; - phy_fapi_config.carrier_cfg = &carrier_cfg; - phy_fapi_config.prach_ports = std::move(prach_ports); - - phy_fapi_adaptor_factory_dependencies phy_fapi_dependencies; - phy_fapi_dependencies.logger = &srslog::fetch_basic_logger("FAPI"); - phy_fapi_dependencies.dl_processor_pool = &dl_processor_pool; - phy_fapi_dependencies.dl_rg_pool = &dl_rg_pool; - phy_fapi_dependencies.dl_pdu_validator = &dl_pdu_validator; - phy_fapi_dependencies.ul_request_processor = &ul_request_processor; - phy_fapi_dependencies.ul_rg_pool = &ul_rg_pool; - phy_fapi_dependencies.ul_pdu_repository = &ul_pdu_repository; - phy_fapi_dependencies.ul_pdu_validator = &ul_pdu_validator; - phy_fapi_dependencies.pm_repo = std::move(pm_repo); - phy_fapi_dependencies.part2_repo = std::move(part2_repo); - - return adaptor_factory->create(phy_fapi_config, std::move(phy_fapi_dependencies)); -} - -std::unique_ptr -srsran::build_mac_fapi_adaptor(unsigned sector_id, - subcarrier_spacing scs, - fapi::slot_message_gateway& gateway, - fapi::slot_last_message_notifier& last_msg_notifier, - std::unique_ptr pm_mapper, - std::unique_ptr part2_mapper, - unsigned cell_nof_prbs) -{ - std::unique_ptr adaptor_factory = create_mac_fapi_adaptor_factory(); - report_error_if_not(adaptor_factory, "Invalid MAC adaptor factory."); - - mac_fapi_adaptor_factory_config mac_fapi_config; - mac_fapi_config.sector_id = sector_id; - mac_fapi_config.cell_nof_prbs = cell_nof_prbs; - mac_fapi_config.scs = scs; - - mac_fapi_adaptor_factory_dependencies mac_fapi_deps; - mac_fapi_deps.gateway = &gateway; - mac_fapi_deps.last_msg_notifier = &last_msg_notifier; - mac_fapi_deps.pm_mapper = std::move(pm_mapper); - mac_fapi_deps.part2_mapper = std::move(part2_mapper); - - return adaptor_factory->create(mac_fapi_config, std::move(mac_fapi_deps)); -} diff --git a/lib/du/adapters/fapi_factory.h b/lib/du/adapters/fapi_factory.h deleted file mode 100644 index e79fc83d4b..0000000000 --- a/lib/du/adapters/fapi_factory.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright 2021-2024 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#pragma once - -#include "srsran/fapi/slot_last_message_notifier.h" -#include "srsran/fapi_adaptor/mac/mac_fapi_adaptor.h" -#include "srsran/fapi_adaptor/phy/phy_fapi_adaptor_factory.h" -#include "srsran/fapi_adaptor/precoding_matrix_mapper.h" -#include "srsran/fapi_adaptor/precoding_matrix_repository.h" -#include "srsran/fapi_adaptor/uci_part2_correspondence_mapper.h" -#include "srsran/fapi_adaptor/uci_part2_correspondence_repository.h" - -namespace srsran { - -std::unique_ptr -build_phy_fapi_adaptor(unsigned sector_id, - unsigned nof_slots_request_headroom, - subcarrier_spacing scs, - subcarrier_spacing scs_common, - downlink_processor_pool& dl_processor_pool, - resource_grid_pool& dl_rg_pool, - uplink_request_processor& ul_request_processor, - resource_grid_pool& ul_rg_pool, - uplink_slot_pdu_repository& ul_pdu_repository, - const downlink_pdu_validator& dl_pdu_validator, - const uplink_pdu_validator& ul_pdu_validator, - const fapi::prach_config& prach_cfg, - const fapi::carrier_config& carrier_cfg, - std::unique_ptr pm_repo, - std::unique_ptr part2_repo, - std::vector prach_ports); - -std::unique_ptr -build_mac_fapi_adaptor(unsigned sector_id, - subcarrier_spacing scs, - fapi::slot_message_gateway& gateway, - fapi::slot_last_message_notifier& last_msg_notifier, - std::unique_ptr pm_mapper, - std::unique_ptr part2_mapper, - unsigned cell_nof_prbs); - -} // namespace srsran diff --git a/lib/du/du_cell_config_validation.cpp b/lib/du/du_cell_config_validation.cpp index 39e372b09e..4cd9bdf446 100644 --- a/lib/du/du_cell_config_validation.cpp +++ b/lib/du/du_cell_config_validation.cpp @@ -9,7 +9,7 @@ */ #include "srsran/du/du_cell_config_validation.h" -#include "../du_manager/ran_resource_management/pucch_resource_generator.h" +#include "du_high/du_manager/ran_resource_management/pucch_resource_generator.h" #include "srsran/asn1/rrc_nr/serving_cell.h" #include "srsran/ran/band_helper.h" #include "srsran/ran/pdcch/pdcch_candidates.h" diff --git a/lib/du/du_high/CMakeLists.txt b/lib/du/du_high/CMakeLists.txt new file mode 100644 index 0000000000..a3ab912f53 --- /dev/null +++ b/lib/du/du_high/CMakeLists.txt @@ -0,0 +1,20 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +add_subdirectory(adapters) +add_subdirectory(du_manager) + +add_library(srsran_du_high STATIC + du_high_impl.cpp + du_high_factory.cpp) +target_link_libraries(srsran_du_high PUBLIC srsran_du_high_adapters) + +add_library(srsran_du_high_wrapper STATIC + du_high_wrapper_factory.cpp + du_high_wrapper_impl.cpp) +target_link_libraries(srsran_du_high_wrapper PUBLIC srsran_du_config_validators srsran_du_high srsran_mac_fapi_adaptor srsran_fapi) diff --git a/lib/du/du_high/adapters/CMakeLists.txt b/lib/du/du_high/adapters/CMakeLists.txt new file mode 100644 index 0000000000..9b186c2b55 --- /dev/null +++ b/lib/du/du_high/adapters/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +add_library(srsran_du_high_adapters + mac_test_mode_adapter.cpp + f1ap_test_mode_adapter.cpp) +target_link_libraries(srsran_du_high_adapters srslog srsran_support srsran_du_manager srsran_mac srsran_f1ap_du srsran_e2) diff --git a/lib/du_high/adapters/adapters.h b/lib/du/du_high/adapters/adapters.h similarity index 95% rename from lib/du_high/adapters/adapters.h rename to lib/du/du_high/adapters/adapters.h index 744ef1ca73..54dc86eb70 100644 --- a/lib/du_high/adapters/adapters.h +++ b/lib/du/du_high/adapters/adapters.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/mac/mac.h" #include "srsran/mac/mac_cell_control_information_handler.h" diff --git a/lib/du_high/adapters/du_high_adapter_factories.h b/lib/du/du_high/adapters/du_high_adapter_factories.h similarity index 71% rename from lib/du_high/adapters/du_high_adapter_factories.h rename to lib/du/du_high/adapters/du_high_adapter_factories.h index 02e24580bb..9d086079a7 100644 --- a/lib/du_high/adapters/du_high_adapter_factories.h +++ b/lib/du/du_high/adapters/du_high_adapter_factories.h @@ -10,13 +10,14 @@ #pragma once -#include "srsran/du/du_test_config.h" +#include "srsran/du/du_high/du_test_mode_config.h" #include "srsran/mac/mac.h" #include "srsran/mac/mac_config.h" namespace srsran { /// \brief Create a MAC instance for DU-high. In case the test mode is enabled, the MAC messages will be intercepted. -std::unique_ptr create_du_high_mac(const mac_config& mac_cfg, const srs_du::du_test_config& test_cfg); +std::unique_ptr create_du_high_mac(const mac_config& mac_cfg, + const srs_du::du_test_mode_config& test_cfg); -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/du_high/adapters/f1ap_adapters.h b/lib/du/du_high/adapters/f1ap_adapters.h similarity index 98% rename from lib/du_high/adapters/f1ap_adapters.h rename to lib/du/du_high/adapters/f1ap_adapters.h index b828a4f2f0..6f5c1e9e34 100644 --- a/lib/du_high/adapters/f1ap_adapters.h +++ b/lib/du/du_high/adapters/f1ap_adapters.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/support/async/execute_on.h" #include "srsran/support/timers.h" diff --git a/lib/du_high/adapters/f1ap_test_mode_adapter.cpp b/lib/du/du_high/adapters/f1ap_test_mode_adapter.cpp similarity index 94% rename from lib/du_high/adapters/f1ap_test_mode_adapter.cpp rename to lib/du/du_high/adapters/f1ap_test_mode_adapter.cpp index 321bc20652..8a94237e9b 100644 --- a/lib/du_high/adapters/f1ap_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/f1ap_test_mode_adapter.cpp @@ -22,9 +22,9 @@ namespace { class f1ap_test_mode_adapter final : public f1ap_du, public f1c_connection_client { public: - f1ap_test_mode_adapter(const du_test_config::test_ue_config& test_ue_cfg_, - f1c_connection_client& f1c_client_handler_, - task_executor& ctrl_exec_) : + f1ap_test_mode_adapter(const du_test_mode_config::test_mode_ue_config& test_ue_cfg_, + f1c_connection_client& f1c_client_handler_, + task_executor& ctrl_exec_) : test_ue_cfg(test_ue_cfg_), f1c_client(f1c_client_handler_), ctrl_exec(ctrl_exec_) { } @@ -139,10 +139,10 @@ class f1ap_test_mode_adapter final : public f1ap_du, public f1c_connection_clien } } - const du_test_config::test_ue_config& test_ue_cfg; - f1c_connection_client& f1c_client; - task_executor& ctrl_exec; - srslog::basic_logger& logger = srslog::fetch_basic_logger("DU-F1"); + const du_test_mode_config::test_mode_ue_config& test_ue_cfg; + f1c_connection_client& f1c_client; + task_executor& ctrl_exec; + srslog::basic_logger& logger = srslog::fetch_basic_logger("DU-F1"); std::unordered_map du_ue_to_rnti; @@ -234,7 +234,7 @@ std::unique_ptr srsran::srs_du::create_du_high_f1ap(f1c_connection_clie task_executor& ctrl_exec, du_high_ue_executor_mapper& ue_exec_mapper, f1ap_du_paging_notifier& paging_notifier, - const du_test_config& test_cfg) + const du_test_mode_config& test_cfg) { if (not test_cfg.test_ue.has_value()) { return create_f1ap(f1c_client_handler, du_mng, ctrl_exec, ue_exec_mapper, paging_notifier); diff --git a/lib/du_high/adapters/f1ap_test_mode_adapter.h b/lib/du/du_high/adapters/f1ap_test_mode_adapter.h similarity index 80% rename from lib/du_high/adapters/f1ap_test_mode_adapter.h rename to lib/du/du_high/adapters/f1ap_test_mode_adapter.h index 277b13a73e..07985f63f1 100644 --- a/lib/du_high/adapters/f1ap_test_mode_adapter.h +++ b/lib/du/du_high/adapters/f1ap_test_mode_adapter.h @@ -10,8 +10,8 @@ #pragma once -#include "srsran/du/du_test_config.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_test_mode_config.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/f1ap/gateways/f1c_connection_client.h" #include @@ -25,7 +25,7 @@ std::unique_ptr create_du_high_f1ap(f1c_connection_client& f1c_cli task_executor& ctrl_exec, du_high_ue_executor_mapper& ue_exec_mapper, f1ap_du_paging_notifier& paging_notifier, - const du_test_config& test_cfg); + const du_test_mode_config& test_cfg); } // namespace srs_du -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/du_high/adapters/mac_test_mode_adapter.cpp b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp similarity index 95% rename from lib/du_high/adapters/mac_test_mode_adapter.cpp rename to lib/du/du_high/adapters/mac_test_mode_adapter.cpp index d148ddc10b..9fb580b17b 100644 --- a/lib/du_high/adapters/mac_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp @@ -71,14 +71,15 @@ class test_ue_mac_sdu_tx_builder_adapter : public mac_sdu_tx_builder } // namespace -mac_test_mode_cell_adapter::mac_test_mode_cell_adapter(const srs_du::du_test_config::test_ue_config& test_ue_cfg_, - const mac_cell_creation_request& cell_cfg, - mac_cell_control_information_handler& adapted_, - mac_pdu_handler& pdu_handler_, - mac_cell_slot_handler& slot_handler_, - mac_cell_result_notifier& result_notifier_, - std::function dl_bs_notifier_, - test_ue_info_manager& ue_info_mgr_) : +mac_test_mode_cell_adapter::mac_test_mode_cell_adapter( + const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg_, + const mac_cell_creation_request& cell_cfg, + mac_cell_control_information_handler& adapted_, + mac_pdu_handler& pdu_handler_, + mac_cell_slot_handler& slot_handler_, + mac_cell_result_notifier& result_notifier_, + std::function dl_bs_notifier_, + test_ue_info_manager& ue_info_mgr_) : test_ue_cfg(test_ue_cfg_), adapted(adapted_), pdu_handler(pdu_handler_), @@ -534,8 +535,8 @@ void phy_test_mode_adapter::phy_cell::on_cell_results_completion(slot_point slot // ---- -mac_test_mode_adapter::mac_test_mode_adapter(const srs_du::du_test_config::test_ue_config& test_ue_cfg_, - mac_result_notifier& phy_notifier_) : +mac_test_mode_adapter::mac_test_mode_adapter(const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg_, + mac_result_notifier& phy_notifier_) : test_ue(test_ue_cfg_), phy_notifier(std::make_unique(phy_notifier_)), ue_info_mgr(test_ue.rnti, test_ue.nof_ues) @@ -678,8 +679,8 @@ void mac_test_mode_adapter::handle_ue_config_applied(du_ue_index_t ue_idx) mac_adapted->get_ue_configurator().handle_ue_config_applied(ue_idx); } -std::unique_ptr srsran::create_du_high_mac(const mac_config& mac_cfg, - const srs_du::du_test_config& test_cfg) +std::unique_ptr srsran::create_du_high_mac(const mac_config& mac_cfg, + const srs_du::du_test_mode_config& test_cfg) { if (not test_cfg.test_ue.has_value()) { return create_mac(mac_cfg); diff --git a/lib/du_high/adapters/mac_test_mode_adapter.h b/lib/du/du_high/adapters/mac_test_mode_adapter.h similarity index 87% rename from lib/du_high/adapters/mac_test_mode_adapter.h rename to lib/du/du_high/adapters/mac_test_mode_adapter.h index e581c8e175..60f8be14a1 100644 --- a/lib/du_high/adapters/mac_test_mode_adapter.h +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du/du_test_config.h" +#include "srsran/du/du_high/du_test_mode_config.h" #include "srsran/mac/mac.h" #include "srsran/mac/mac_cell_result.h" #include "srsran/srslog/srslog.h" @@ -121,14 +121,14 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler, public mac_cell_slot_handler { public: - mac_test_mode_cell_adapter(const srs_du::du_test_config::test_ue_config& test_ue_cfg_, - const mac_cell_creation_request& cell_cfg, - mac_cell_control_information_handler& adapted_, - mac_pdu_handler& pdu_handler_, - mac_cell_slot_handler& slot_handler_, - mac_cell_result_notifier& result_notifier_, - std::function dl_bs_notifier_, - test_ue_info_manager& ue_info_mgr_); + mac_test_mode_cell_adapter(const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg_, + const mac_cell_creation_request& cell_cfg, + mac_cell_control_information_handler& adapted_, + mac_pdu_handler& pdu_handler_, + mac_cell_slot_handler& slot_handler_, + mac_cell_result_notifier& result_notifier_, + std::function dl_bs_notifier_, + test_ue_info_manager& ue_info_mgr_); void on_new_downlink_scheduler_results(const mac_dl_sched_result& dl_res) override { @@ -165,13 +165,13 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler, void forward_uci_ind_to_mac(const mac_uci_indication_message& uci_msg); void forward_crc_ind_to_mac(const mac_crc_indication_message& crc_msg); - const srs_du::du_test_config::test_ue_config& test_ue_cfg; - mac_cell_control_information_handler& adapted; - mac_pdu_handler& pdu_handler; - mac_cell_slot_handler& slot_handler; - mac_cell_result_notifier& result_notifier; - std::function dl_bs_notifier; - srslog::basic_logger& logger; + const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg; + mac_cell_control_information_handler& adapted; + mac_pdu_handler& pdu_handler; + mac_cell_slot_handler& slot_handler; + mac_cell_result_notifier& result_notifier; + std::function dl_bs_notifier; + srslog::basic_logger& logger; std::vector sched_decision_history; @@ -184,8 +184,8 @@ class mac_test_mode_adapter final : public mac_interface, public mac_cell_manager { public: - explicit mac_test_mode_adapter(const srs_du::du_test_config::test_ue_config& test_ue_cfg, - mac_result_notifier& phy_notifier_); + explicit mac_test_mode_adapter(const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg, + mac_result_notifier& phy_notifier_); ~mac_test_mode_adapter() override; void connect(std::unique_ptr mac_ptr); @@ -236,8 +236,8 @@ class mac_test_mode_adapter final : public mac_interface, std::vector adapt_bearers(const std::vector& orig_bearers) const; - srs_du::du_test_config::test_ue_config test_ue; - std::unique_ptr mac_adapted; + srs_du::du_test_mode_config::test_mode_ue_config test_ue; + std::unique_ptr mac_adapted; std::unique_ptr phy_notifier; diff --git a/lib/du_high/du_high_executor_strategies.h b/lib/du/du_high/du_high_executor_strategies.h similarity index 99% rename from lib/du_high/du_high_executor_strategies.h rename to lib/du/du_high/du_high_executor_strategies.h index 250d9da97e..c70f8f589b 100644 --- a/lib/du_high/du_high_executor_strategies.h +++ b/lib/du/du_high/du_high_executor_strategies.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/support/srsran_assert.h" namespace srsran { diff --git a/lib/du_high/du_high_factory.cpp b/lib/du/du_high/du_high_factory.cpp similarity index 89% rename from lib/du_high/du_high_factory.cpp rename to lib/du/du_high/du_high_factory.cpp index 89bd661fee..19b69ed4b1 100644 --- a/lib/du_high/du_high_factory.cpp +++ b/lib/du/du_high/du_high_factory.cpp @@ -8,7 +8,7 @@ * */ -#include "srsran/du_high/du_high_factory.h" +#include "srsran/du/du_high/du_high_factory.h" #include "du_high_impl.h" using namespace srsran; @@ -16,4 +16,4 @@ using namespace srsran; std::unique_ptr srsran::make_du_high(const srs_du::du_high_configuration& du_hi_cfg) { return std::make_unique(du_hi_cfg); -} \ No newline at end of file +} diff --git a/lib/du_high/du_high_impl.cpp b/lib/du/du_high/du_high_impl.cpp similarity index 99% rename from lib/du_high/du_high_impl.cpp rename to lib/du/du_high/du_high_impl.cpp index 1a531db0b3..7adf1720a5 100644 --- a/lib/du_high/du_high_impl.cpp +++ b/lib/du/du_high/du_high_impl.cpp @@ -14,7 +14,7 @@ #include "adapters/f1ap_adapters.h" #include "adapters/f1ap_test_mode_adapter.h" #include "du_high_executor_strategies.h" -#include "srsran/du_manager/du_manager_factory.h" +#include "srsran/du/du_high/du_manager/du_manager_factory.h" #include "srsran/e2/e2.h" #include "srsran/e2/e2_factory.h" #include "srsran/f1ap/du/f1ap_du_factory.h" diff --git a/lib/du_high/du_high_impl.h b/lib/du/du_high/du_high_impl.h similarity index 92% rename from lib/du_high/du_high_impl.h rename to lib/du/du_high/du_high_impl.h index 7aebc5c34f..4ec2872844 100644 --- a/lib/du_high/du_high_impl.h +++ b/lib/du/du_high/du_high_impl.h @@ -10,9 +10,9 @@ #pragma once -#include "srsran/du_high/du_high.h" -#include "srsran/du_high/du_high_configuration.h" -#include "srsran/du_manager/du_manager.h" +#include "srsran/du/du_high/du_high.h" +#include "srsran/du/du_high/du_high_configuration.h" +#include "srsran/du/du_high/du_manager/du_manager.h" #include "srsran/e2/e2.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/mac/mac.h" diff --git a/lib/du/du_high_wrapper_factory.cpp b/lib/du/du_high/du_high_wrapper_factory.cpp similarity index 88% rename from lib/du/du_high_wrapper_factory.cpp rename to lib/du/du_high/du_high_wrapper_factory.cpp index c61dc13107..b5cdb1a1fa 100644 --- a/lib/du/du_high_wrapper_factory.cpp +++ b/lib/du/du_high/du_high_wrapper_factory.cpp @@ -8,18 +8,45 @@ * */ -#include "srsran/du/du_high_wrapper_factory.h" -#include "adapters/fapi_factory.h" +#include "srsran/du/du_high/du_high_wrapper_factory.h" #include "du_high_wrapper_impl.h" -#include "srsran/du_high/du_high_factory.h" +#include "srsran/du/du_high/du_high_factory.h" #include "srsran/fapi/buffered_decorator_factories.h" #include "srsran/fapi/logging_decorator_factories.h" #include "srsran/fapi/messages.h" +#include "srsran/fapi_adaptor/mac/mac_fapi_adaptor_factory.h" #include "srsran/fapi_adaptor/precoding_matrix_table_generator.h" #include "srsran/fapi_adaptor/uci_part2_correspondence_generator.h" using namespace srsran; +static std::unique_ptr +build_mac_fapi_adaptor(unsigned sector_id, + subcarrier_spacing scs, + fapi::slot_message_gateway& gateway, + fapi::slot_last_message_notifier& last_msg_notifier, + std::unique_ptr pm_mapper, + std::unique_ptr part2_mapper, + unsigned cell_nof_prbs) +{ + std::unique_ptr adaptor_factory = + fapi_adaptor::create_mac_fapi_adaptor_factory(); + report_error_if_not(adaptor_factory, "Invalid MAC adaptor factory."); + + fapi_adaptor::mac_fapi_adaptor_factory_config mac_fapi_config; + mac_fapi_config.sector_id = sector_id; + mac_fapi_config.cell_nof_prbs = cell_nof_prbs; + mac_fapi_config.scs = scs; + + fapi_adaptor::mac_fapi_adaptor_factory_dependencies mac_fapi_deps; + mac_fapi_deps.gateway = &gateway; + mac_fapi_deps.last_msg_notifier = &last_msg_notifier; + mac_fapi_deps.pm_mapper = std::move(pm_mapper); + mac_fapi_deps.part2_mapper = std::move(part2_mapper); + + return adaptor_factory->create(mac_fapi_config, std::move(mac_fapi_deps)); +} + static std::unique_ptr build_fapi_adaptors(const du_cell_config& du_cell, du_high_wrapper_sector_dependencies& dependencies, unsigned sector) { @@ -249,4 +276,4 @@ std::unique_ptr srsran::make_du_high_wrapper(const du_high_wrap logger.info("DU created successfully"); return wrapper_du; -} \ No newline at end of file +} diff --git a/lib/du/du_high_wrapper_impl.cpp b/lib/du/du_high/du_high_wrapper_impl.cpp similarity index 100% rename from lib/du/du_high_wrapper_impl.cpp rename to lib/du/du_high/du_high_wrapper_impl.cpp diff --git a/lib/du/du_high_wrapper_impl.h b/lib/du/du_high/du_high_wrapper_impl.h similarity index 95% rename from lib/du/du_high_wrapper_impl.h rename to lib/du/du_high/du_high_wrapper_impl.h index beb5c14dd8..d4951a203e 100644 --- a/lib/du/du_high_wrapper_impl.h +++ b/lib/du/du_high/du_high_wrapper_impl.h @@ -10,9 +10,9 @@ #pragma once -#include "srsran/du/du_high_wrapper.h" +#include "srsran/du/du_high/du_high.h" +#include "srsran/du/du_high/du_high_wrapper.h" #include "srsran/du/du_wrapper_config.h" -#include "srsran/du_high/du_high.h" #include "srsran/fapi_adaptor/mac/mac_fapi_adaptor.h" namespace srsran { diff --git a/lib/du/du_high/du_manager/CMakeLists.txt b/lib/du/du_high/du_manager/CMakeLists.txt new file mode 100644 index 0000000000..8a8ed6122d --- /dev/null +++ b/lib/du/du_high/du_manager/CMakeLists.txt @@ -0,0 +1,28 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +add_subdirectory(converters) +add_subdirectory(du_ue) +add_subdirectory(procedures) +add_subdirectory(ran_resource_management) + +set(SOURCES + du_cell_manager.cpp + du_manager_factory.cpp + du_manager_impl.cpp) + +add_library(srsran_du_manager STATIC ${SOURCES}) +target_link_libraries(srsran_du_manager + du_ue + du_resource_manager + du_manager_converters + srsran_du_config_validators + mac_configuration_helpers + srsran_rlc + srsran_f1u_du + srsran_gtpu) diff --git a/lib/du_manager/converters/CMakeLists.txt b/lib/du/du_high/du_manager/converters/CMakeLists.txt similarity index 90% rename from lib/du_manager/converters/CMakeLists.txt rename to lib/du/du_high/du_manager/converters/CMakeLists.txt index 1e6d1f58e7..6e6ceda7be 100644 --- a/lib/du_manager/converters/CMakeLists.txt +++ b/lib/du/du_high/du_manager/converters/CMakeLists.txt @@ -7,9 +7,10 @@ # -set(SOURCES f1ap_configuration_helpers.cpp - asn1_rrc_config_helpers.cpp +set(SOURCES asn1_csi_meas_config_helpers.cpp + asn1_rrc_config_helpers.cpp + f1ap_configuration_helpers.cpp rlc_config_helpers.cpp scheduler_configuration_helpers.cpp) diff --git a/lib/du_manager/converters/asn1_csi_meas_config_helpers.cpp b/lib/du/du_high/du_manager/converters/asn1_csi_meas_config_helpers.cpp similarity index 99% rename from lib/du_manager/converters/asn1_csi_meas_config_helpers.cpp rename to lib/du/du_high/du_manager/converters/asn1_csi_meas_config_helpers.cpp index be7c3e157c..742001fd85 100644 --- a/lib/du_manager/converters/asn1_csi_meas_config_helpers.cpp +++ b/lib/du/du_high/du_manager/converters/asn1_csi_meas_config_helpers.cpp @@ -9,7 +9,7 @@ */ #include "asn1_csi_meas_config_helpers.h" -#include "../../asn1/asn1_diff_utils.h" +#include "srsran/asn1/asn1_diff_utils.h" #include "srsran/asn1/rrc_nr/serving_cell.h" using namespace srsran; diff --git a/lib/du_manager/converters/asn1_csi_meas_config_helpers.h b/lib/du/du_high/du_manager/converters/asn1_csi_meas_config_helpers.h similarity index 100% rename from lib/du_manager/converters/asn1_csi_meas_config_helpers.h rename to lib/du/du_high/du_manager/converters/asn1_csi_meas_config_helpers.h diff --git a/lib/du_manager/converters/asn1_rrc_config_helpers.cpp b/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp similarity index 99% rename from lib/du_manager/converters/asn1_rrc_config_helpers.cpp rename to lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp index a6f42c4ea4..267e3e7e43 100644 --- a/lib/du_manager/converters/asn1_rrc_config_helpers.cpp +++ b/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp @@ -9,8 +9,8 @@ */ #include "asn1_rrc_config_helpers.h" -#include "../../asn1/asn1_diff_utils.h" #include "asn1_csi_meas_config_helpers.h" +#include "srsran/asn1/asn1_diff_utils.h" #include "srsran/support/error_handling.h" using namespace srsran; diff --git a/lib/du_manager/converters/asn1_rrc_config_helpers.h b/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.h similarity index 100% rename from lib/du_manager/converters/asn1_rrc_config_helpers.h rename to lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.h diff --git a/lib/du_manager/converters/f1ap_configuration_helpers.cpp b/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.cpp similarity index 100% rename from lib/du_manager/converters/f1ap_configuration_helpers.cpp rename to lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.cpp diff --git a/lib/du_manager/converters/f1ap_configuration_helpers.h b/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h similarity index 97% rename from lib/du_manager/converters/f1ap_configuration_helpers.h rename to lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h index ff3dc2e6c0..53277dc049 100644 --- a/lib/du_manager/converters/f1ap_configuration_helpers.h +++ b/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h @@ -12,7 +12,7 @@ #include "srsran/adt/byte_buffer.h" #include "srsran/du/du_cell_config.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/ran/ntn.h" namespace srsran { diff --git a/lib/du_manager/converters/rlc_config_helpers.cpp b/lib/du/du_high/du_manager/converters/rlc_config_helpers.cpp similarity index 100% rename from lib/du_manager/converters/rlc_config_helpers.cpp rename to lib/du/du_high/du_manager/converters/rlc_config_helpers.cpp diff --git a/lib/du_manager/converters/rlc_config_helpers.h b/lib/du/du_high/du_manager/converters/rlc_config_helpers.h similarity index 97% rename from lib/du_manager/converters/rlc_config_helpers.h rename to lib/du/du_high/du_manager/converters/rlc_config_helpers.h index 831e382950..3f09208a6d 100644 --- a/lib/du_manager/converters/rlc_config_helpers.h +++ b/lib/du/du_high/du_manager/converters/rlc_config_helpers.h @@ -11,7 +11,7 @@ #pragma once #include "../du_ue/du_bearer.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/f1ap/du/f1ap_du_ue_config.h" #include "srsran/mac/mac_lc_config.h" #include "srsran/ran/du_types.h" diff --git a/lib/du_manager/converters/scheduler_configuration_helpers.cpp b/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.cpp similarity index 100% rename from lib/du_manager/converters/scheduler_configuration_helpers.cpp rename to lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.cpp diff --git a/lib/du_manager/converters/scheduler_configuration_helpers.h b/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h similarity index 100% rename from lib/du_manager/converters/scheduler_configuration_helpers.h rename to lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h diff --git a/lib/du_manager/du_cell_manager.cpp b/lib/du/du_high/du_manager/du_cell_manager.cpp similarity index 100% rename from lib/du_manager/du_cell_manager.cpp rename to lib/du/du_high/du_manager/du_cell_manager.cpp diff --git a/lib/du_manager/du_cell_manager.h b/lib/du/du_high/du_manager/du_cell_manager.h similarity index 96% rename from lib/du_manager/du_cell_manager.h rename to lib/du/du_high/du_manager/du_cell_manager.h index b75a06d413..368d944ce2 100644 --- a/lib/du_manager/du_cell_manager.h +++ b/lib/du/du_high/du_manager/du_cell_manager.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/ran/du_types.h" namespace srsran { diff --git a/lib/du_manager/du_manager_factory.cpp b/lib/du/du_high/du_manager/du_manager_factory.cpp similarity index 89% rename from lib/du_manager/du_manager_factory.cpp rename to lib/du/du_high/du_manager/du_manager_factory.cpp index 750b00ff3f..c007907f36 100644 --- a/lib/du_manager/du_manager_factory.cpp +++ b/lib/du/du_high/du_manager/du_manager_factory.cpp @@ -8,7 +8,7 @@ * */ -#include "srsran/du_manager/du_manager_factory.h" +#include "srsran/du/du_high/du_manager/du_manager_factory.h" #include "du_manager_impl.h" using namespace srsran; diff --git a/lib/du_manager/du_manager_impl.cpp b/lib/du/du_high/du_manager/du_manager_impl.cpp similarity index 100% rename from lib/du_manager/du_manager_impl.cpp rename to lib/du/du_high/du_manager/du_manager_impl.cpp diff --git a/lib/du_manager/du_manager_impl.h b/lib/du/du_high/du_manager/du_manager_impl.h similarity index 95% rename from lib/du_manager/du_manager_impl.h rename to lib/du/du_high/du_manager/du_manager_impl.h index 771e687b05..13f12e8079 100644 --- a/lib/du_manager/du_manager_impl.h +++ b/lib/du/du_high/du_manager/du_manager_impl.h @@ -13,8 +13,8 @@ #include "du_cell_manager.h" #include "du_ue/du_ue_manager.h" #include "ran_resource_management/du_ran_resource_manager_impl.h" -#include "srsran/du_manager/du_manager.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include namespace srsran { diff --git a/lib/du_manager/du_ue/CMakeLists.txt b/lib/du/du_high/du_manager/du_ue/CMakeLists.txt similarity index 53% rename from lib/du_manager/du_ue/CMakeLists.txt rename to lib/du/du_high/du_manager/du_ue/CMakeLists.txt index 913ad7dbd0..7b097aafa6 100644 --- a/lib/du_manager/du_ue/CMakeLists.txt +++ b/lib/du/du_high/du_manager/du_ue/CMakeLists.txt @@ -6,4 +6,6 @@ # the distribution. # -add_library(du_ue du_bearer.cpp du_ue_bearer_manager.cpp du_ue_adapters.cpp du_ue_controller_impl.cpp) +add_library(du_ue du_bearer.cpp du_ue_adapters.cpp du_ue_bearer_manager.cpp du_ue_controller_impl.cpp du_ue_manager.cpp) + +target_link_libraries(du_ue PUBLIC srsran_du_manager_procedures) diff --git a/lib/du_manager/du_ue/du_bearer.cpp b/lib/du/du_high/du_manager/du_ue/du_bearer.cpp similarity index 99% rename from lib/du_manager/du_ue/du_bearer.cpp rename to lib/du/du_high/du_manager/du_ue/du_bearer.cpp index dc0a668758..f8ee1540dd 100644 --- a/lib/du_manager/du_ue/du_bearer.cpp +++ b/lib/du/du_high/du_manager/du_ue/du_bearer.cpp @@ -10,7 +10,7 @@ #include "du_bearer.h" #include "../converters/rlc_config_helpers.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/f1u/du/f1u_bearer_factory.h" #include "srsran/gtpu/gtpu_teid_pool.h" #include "srsran/srslog/srslog.h" diff --git a/lib/du_manager/du_ue/du_bearer.h b/lib/du/du_high/du_manager/du_ue/du_bearer.h similarity index 100% rename from lib/du_manager/du_ue/du_bearer.h rename to lib/du/du_high/du_manager/du_ue/du_bearer.h diff --git a/lib/du_manager/du_ue/du_ue.h b/lib/du/du_high/du_manager/du_ue/du_ue.h similarity index 100% rename from lib/du_manager/du_ue/du_ue.h rename to lib/du/du_high/du_manager/du_ue/du_ue.h diff --git a/lib/du_manager/du_ue/du_ue_adapters.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_adapters.cpp similarity index 100% rename from lib/du_manager/du_ue/du_ue_adapters.cpp rename to lib/du/du_high/du_manager/du_ue/du_ue_adapters.cpp diff --git a/lib/du_manager/du_ue/du_ue_adapters.h b/lib/du/du_high/du_manager/du_ue/du_ue_adapters.h similarity index 100% rename from lib/du_manager/du_ue/du_ue_adapters.h rename to lib/du/du_high/du_manager/du_ue/du_ue_adapters.h diff --git a/lib/du_manager/du_ue/du_ue_bearer_manager.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_bearer_manager.cpp similarity index 100% rename from lib/du_manager/du_ue/du_ue_bearer_manager.cpp rename to lib/du/du_high/du_manager/du_ue/du_ue_bearer_manager.cpp diff --git a/lib/du_manager/du_ue/du_ue_bearer_manager.h b/lib/du/du_high/du_manager/du_ue/du_ue_bearer_manager.h similarity index 100% rename from lib/du_manager/du_ue/du_ue_bearer_manager.h rename to lib/du/du_high/du_manager/du_ue/du_ue_bearer_manager.h diff --git a/lib/du_manager/du_ue/du_ue_controller_impl.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp similarity index 100% rename from lib/du_manager/du_ue/du_ue_controller_impl.cpp rename to lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp diff --git a/lib/du_manager/du_ue/du_ue_controller_impl.h b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.h similarity index 100% rename from lib/du_manager/du_ue/du_ue_controller_impl.h rename to lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.h diff --git a/lib/du_manager/du_ue/du_ue_manager.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_manager.cpp similarity index 100% rename from lib/du_manager/du_ue/du_ue_manager.cpp rename to lib/du/du_high/du_manager/du_ue/du_ue_manager.cpp diff --git a/lib/du_manager/du_ue/du_ue_manager.h b/lib/du/du_high/du_manager/du_ue/du_ue_manager.h similarity index 97% rename from lib/du_manager/du_ue/du_ue_manager.h rename to lib/du/du_high/du_manager/du_ue/du_ue_manager.h index bd25aee92b..dfd942edf7 100644 --- a/lib/du_manager/du_ue/du_ue_manager.h +++ b/lib/du/du_high/du_manager/du_ue/du_ue_manager.h @@ -14,8 +14,8 @@ #include "du_ue_controller_impl.h" #include "du_ue_manager_repository.h" #include "srsran/adt/slotted_array.h" -#include "srsran/du_manager/du_manager.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/support/async/fifo_async_task_scheduler.h" #include diff --git a/lib/du_manager/du_ue/du_ue_manager_repository.h b/lib/du/du_high/du_manager/du_ue/du_ue_manager_repository.h similarity index 100% rename from lib/du_manager/du_ue/du_ue_manager_repository.h rename to lib/du/du_high/du_manager/du_ue/du_ue_manager_repository.h diff --git a/lib/du_manager/procedures/CMakeLists.txt b/lib/du/du_high/du_manager/procedures/CMakeLists.txt similarity index 86% rename from lib/du_manager/procedures/CMakeLists.txt rename to lib/du/du_high/du_manager/procedures/CMakeLists.txt index 5c3bdfa6c7..bcc11826b6 100644 --- a/lib/du_manager/procedures/CMakeLists.txt +++ b/lib/du/du_high/du_manager/procedures/CMakeLists.txt @@ -7,12 +7,12 @@ # set(SOURCES - initial_du_setup_procedure.cpp du_stop_procedure.cpp - ue_creation_procedure.cpp + du_ue_ric_configuration_procedure.cpp + initial_du_setup_procedure.cpp ue_configuration_procedure.cpp - ue_deletion_procedure.cpp - du_ue_ric_configuration_procedure.cpp) + ue_creation_procedure.cpp + ue_deletion_procedure.cpp) add_library(srsran_du_manager_procedures STATIC ${SOURCES}) target_link_libraries(srsran_du_manager_procedures sched_config srsran_ran mac_configuration_helpers du_ue) diff --git a/lib/du_manager/procedures/du_stop_procedure.cpp b/lib/du/du_high/du_manager/procedures/du_stop_procedure.cpp similarity index 100% rename from lib/du_manager/procedures/du_stop_procedure.cpp rename to lib/du/du_high/du_manager/procedures/du_stop_procedure.cpp diff --git a/lib/du_manager/procedures/du_stop_procedure.h b/lib/du/du_high/du_manager/procedures/du_stop_procedure.h similarity index 92% rename from lib/du_manager/procedures/du_stop_procedure.h rename to lib/du/du_high/du_manager/procedures/du_stop_procedure.h index ff7a0fafab..ac7e2c155f 100644 --- a/lib/du_manager/procedures/du_stop_procedure.h +++ b/lib/du/du_high/du_manager/procedures/du_stop_procedure.h @@ -13,7 +13,7 @@ #include "../du_cell_manager.h" #include "../du_ue/du_ue_manager.h" #include "procedure_logger.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/support/async/async_task.h" namespace srsran { @@ -38,4 +38,4 @@ class du_stop_procedure }; } // namespace srs_du -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/du_manager/procedures/du_ue_ric_configuration_procedure.cpp b/lib/du/du_high/du_manager/procedures/du_ue_ric_configuration_procedure.cpp similarity index 100% rename from lib/du_manager/procedures/du_ue_ric_configuration_procedure.cpp rename to lib/du/du_high/du_manager/procedures/du_ue_ric_configuration_procedure.cpp diff --git a/lib/du_manager/procedures/du_ue_ric_configuration_procedure.h b/lib/du/du_high/du_manager/procedures/du_ue_ric_configuration_procedure.h similarity index 94% rename from lib/du_manager/procedures/du_ue_ric_configuration_procedure.h rename to lib/du/du_high/du_manager/procedures/du_ue_ric_configuration_procedure.h index a1f3b81209..02646bbdff 100644 --- a/lib/du_manager/procedures/du_ue_ric_configuration_procedure.h +++ b/lib/du/du_high/du_manager/procedures/du_ue_ric_configuration_procedure.h @@ -12,7 +12,7 @@ #include "../du_ue/du_ue_manager_repository.h" #include "procedure_logger.h" -#include "srsran/du_manager/du_configurator.h" +#include "srsran/du/du_high/du_manager/du_configurator.h" #include "srsran/ran/rrm.h" #include "srsran/support/async/manual_event.h" @@ -46,4 +46,4 @@ class du_ue_ric_configuration_procedure }; } // namespace srs_du -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/du_manager/procedures/initial_du_setup_procedure.cpp b/lib/du/du_high/du_manager/procedures/initial_du_setup_procedure.cpp similarity index 100% rename from lib/du_manager/procedures/initial_du_setup_procedure.cpp rename to lib/du/du_high/du_manager/procedures/initial_du_setup_procedure.cpp diff --git a/lib/du_manager/procedures/initial_du_setup_procedure.h b/lib/du/du_high/du_manager/procedures/initial_du_setup_procedure.h similarity index 100% rename from lib/du_manager/procedures/initial_du_setup_procedure.h rename to lib/du/du_high/du_manager/procedures/initial_du_setup_procedure.h diff --git a/lib/du_manager/procedures/procedure_logger.h b/lib/du/du_high/du_manager/procedures/procedure_logger.h similarity index 100% rename from lib/du_manager/procedures/procedure_logger.h rename to lib/du/du_high/du_manager/procedures/procedure_logger.h diff --git a/lib/du_manager/procedures/ue_configuration_procedure.cpp b/lib/du/du_high/du_manager/procedures/ue_configuration_procedure.cpp similarity index 100% rename from lib/du_manager/procedures/ue_configuration_procedure.cpp rename to lib/du/du_high/du_manager/procedures/ue_configuration_procedure.cpp diff --git a/lib/du_manager/procedures/ue_configuration_procedure.h b/lib/du/du_high/du_manager/procedures/ue_configuration_procedure.h similarity index 97% rename from lib/du_manager/procedures/ue_configuration_procedure.h rename to lib/du/du_high/du_manager/procedures/ue_configuration_procedure.h index 5e5d509321..af03f88aed 100644 --- a/lib/du_manager/procedures/ue_configuration_procedure.h +++ b/lib/du/du_high/du_manager/procedures/ue_configuration_procedure.h @@ -12,7 +12,7 @@ #include "../du_ue/du_ue_manager_repository.h" #include "procedure_logger.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" namespace srsran { namespace srs_du { diff --git a/lib/du_manager/procedures/ue_creation_procedure.cpp b/lib/du/du_high/du_manager/procedures/ue_creation_procedure.cpp similarity index 100% rename from lib/du_manager/procedures/ue_creation_procedure.cpp rename to lib/du/du_high/du_manager/procedures/ue_creation_procedure.cpp diff --git a/lib/du_manager/procedures/ue_creation_procedure.h b/lib/du/du_high/du_manager/procedures/ue_creation_procedure.h similarity index 98% rename from lib/du_manager/procedures/ue_creation_procedure.h rename to lib/du/du_high/du_manager/procedures/ue_creation_procedure.h index caa8a2b040..0596189d94 100644 --- a/lib/du_manager/procedures/ue_creation_procedure.h +++ b/lib/du/du_high/du_manager/procedures/ue_creation_procedure.h @@ -13,7 +13,7 @@ #include "../du_ue/du_ue.h" #include "../du_ue/du_ue_manager_repository.h" #include "procedure_logger.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/mac/config/mac_config_helpers.h" #include "srsran/mac/mac.h" #include "srsran/support/async/async_task.h" diff --git a/lib/du_manager/procedures/ue_deletion_procedure.cpp b/lib/du/du_high/du_manager/procedures/ue_deletion_procedure.cpp similarity index 100% rename from lib/du_manager/procedures/ue_deletion_procedure.cpp rename to lib/du/du_high/du_manager/procedures/ue_deletion_procedure.cpp diff --git a/lib/du_manager/procedures/ue_deletion_procedure.h b/lib/du/du_high/du_manager/procedures/ue_deletion_procedure.h similarity index 91% rename from lib/du_manager/procedures/ue_deletion_procedure.h rename to lib/du/du_high/du_manager/procedures/ue_deletion_procedure.h index 2c641516fb..dc06ae79c5 100644 --- a/lib/du_manager/procedures/ue_deletion_procedure.h +++ b/lib/du/du_high/du_manager/procedures/ue_deletion_procedure.h @@ -13,8 +13,8 @@ #include "../du_ue/du_ue.h" #include "../du_ue/du_ue_manager_repository.h" #include "procedure_logger.h" -#include "srsran/du_manager/du_manager.h" -#include "srsran/du_manager/du_manager_params.h" +#include "srsran/du/du_high/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/support/async/async_task.h" namespace srsran { diff --git a/lib/du_manager/ran_resource_management/CMakeLists.txt b/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt similarity index 100% rename from lib/du_manager/ran_resource_management/CMakeLists.txt rename to lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt index 2924c2760c..a6e7ab5a81 100644 --- a/lib/du_manager/ran_resource_management/CMakeLists.txt +++ b/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt @@ -7,9 +7,9 @@ # add_library(du_resource_manager - du_ran_resource_manager_impl.cpp - du_pucch_resource_manager.cpp du_bearer_resource_manager.cpp + du_pucch_resource_manager.cpp + du_ran_resource_manager_impl.cpp pucch_resource_generator.cpp ue_capability_manager.cpp) target_link_libraries(du_resource_manager du_manager_converters srsran_du_config_validators mac_configuration_helpers) diff --git a/lib/du_manager/ran_resource_management/du_bearer_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_bearer_resource_manager.cpp similarity index 100% rename from lib/du_manager/ran_resource_management/du_bearer_resource_manager.cpp rename to lib/du/du_high/du_manager/ran_resource_management/du_bearer_resource_manager.cpp diff --git a/lib/du_manager/ran_resource_management/du_bearer_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_bearer_resource_manager.h similarity index 100% rename from lib/du_manager/ran_resource_management/du_bearer_resource_manager.h rename to lib/du/du_high/du_manager/ran_resource_management/du_bearer_resource_manager.h diff --git a/lib/du_manager/ran_resource_management/du_pucch_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp similarity index 100% rename from lib/du_manager/ran_resource_management/du_pucch_resource_manager.cpp rename to lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp diff --git a/lib/du_manager/ran_resource_management/du_pucch_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.h similarity index 100% rename from lib/du_manager/ran_resource_management/du_pucch_resource_manager.h rename to lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.h diff --git a/lib/du_manager/ran_resource_management/du_ran_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager.h similarity index 100% rename from lib/du_manager/ran_resource_management/du_ran_resource_manager.h rename to lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager.h diff --git a/lib/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp similarity index 100% rename from lib/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp rename to lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp diff --git a/lib/du_manager/ran_resource_management/du_ran_resource_manager_impl.h b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h similarity index 100% rename from lib/du_manager/ran_resource_management/du_ran_resource_manager_impl.h rename to lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h diff --git a/lib/du_manager/ran_resource_management/du_ue_resource_config.h b/lib/du/du_high/du_manager/ran_resource_management/du_ue_resource_config.h similarity index 100% rename from lib/du_manager/ran_resource_management/du_ue_resource_config.h rename to lib/du/du_high/du_manager/ran_resource_management/du_ue_resource_config.h diff --git a/lib/du_manager/ran_resource_management/pucch_resource_generator.cpp b/lib/du/du_high/du_manager/ran_resource_management/pucch_resource_generator.cpp similarity index 100% rename from lib/du_manager/ran_resource_management/pucch_resource_generator.cpp rename to lib/du/du_high/du_manager/ran_resource_management/pucch_resource_generator.cpp diff --git a/lib/du_manager/ran_resource_management/pucch_resource_generator.h b/lib/du/du_high/du_manager/ran_resource_management/pucch_resource_generator.h similarity index 100% rename from lib/du_manager/ran_resource_management/pucch_resource_generator.h rename to lib/du/du_high/du_manager/ran_resource_management/pucch_resource_generator.h diff --git a/lib/du_manager/ran_resource_management/ue_capability_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/ue_capability_manager.cpp similarity index 100% rename from lib/du_manager/ran_resource_management/ue_capability_manager.cpp rename to lib/du/du_high/du_manager/ran_resource_management/ue_capability_manager.cpp diff --git a/lib/du_manager/ran_resource_management/ue_capability_manager.h b/lib/du/du_high/du_manager/ran_resource_management/ue_capability_manager.h similarity index 100% rename from lib/du_manager/ran_resource_management/ue_capability_manager.h rename to lib/du/du_high/du_manager/ran_resource_management/ue_capability_manager.h diff --git a/lib/du_low/CMakeLists.txt b/lib/du/du_low/CMakeLists.txt similarity index 100% rename from lib/du_low/CMakeLists.txt rename to lib/du/du_low/CMakeLists.txt diff --git a/lib/du_low/du_low_factory.cpp b/lib/du/du_low/du_low_factory.cpp similarity index 96% rename from lib/du_low/du_low_factory.cpp rename to lib/du/du_low/du_low_factory.cpp index 1043647479..32da1e489d 100644 --- a/lib/du_low/du_low_factory.cpp +++ b/lib/du/du_low/du_low_factory.cpp @@ -8,9 +8,9 @@ * */ -#include "srsran/du_low/du_low_factory.h" +#include "srsran/du/du_low/du_low_factory.h" #include "du_low_impl.h" -#include "srsran/du_low/du_low_config.h" +#include "srsran/du/du_low/du_low_config.h" #include "srsran/support/error_handling.h" using namespace srsran; diff --git a/lib/du_low/du_low_impl.cpp b/lib/du/du_low/du_low_impl.cpp similarity index 100% rename from lib/du_low/du_low_impl.cpp rename to lib/du/du_low/du_low_impl.cpp diff --git a/lib/du_low/du_low_impl.h b/lib/du/du_low/du_low_impl.h similarity index 95% rename from lib/du_low/du_low_impl.h rename to lib/du/du_low/du_low_impl.h index 4bc262e2cf..0a732e4acc 100644 --- a/lib/du_low/du_low_impl.h +++ b/lib/du/du_low/du_low_impl.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_low/du_low.h" +#include "srsran/du/du_low/du_low.h" #include "srsran/phy/upper/upper_phy.h" namespace srsran { diff --git a/lib/du_low/du_low_wrapper_factory.cpp b/lib/du/du_low/du_low_wrapper_factory.cpp similarity index 97% rename from lib/du_low/du_low_wrapper_factory.cpp rename to lib/du/du_low/du_low_wrapper_factory.cpp index 03d7000708..1898293525 100644 --- a/lib/du_low/du_low_wrapper_factory.cpp +++ b/lib/du/du_low/du_low_wrapper_factory.cpp @@ -8,11 +8,11 @@ * */ -#include "srsran/du_low/du_low_wrapper_factory.h" +#include "srsran/du/du_low/du_low_wrapper_factory.h" #include "du_low_wrapper_impl.h" #include "srsran/du/du_cell_config.h" -#include "srsran/du_low/du_low_factory.h" -#include "srsran/du_low/du_low_wrapper_config.h" +#include "srsran/du/du_low/du_low_factory.h" +#include "srsran/du/du_low/du_low_wrapper_config.h" #include "srsran/fapi/messages.h" #include "srsran/fapi_adaptor/phy/phy_fapi_adaptor_factory.h" #include "srsran/fapi_adaptor/precoding_matrix_table_generator.h" diff --git a/lib/du_low/du_low_wrapper_impl.cpp b/lib/du/du_low/du_low_wrapper_impl.cpp similarity index 100% rename from lib/du_low/du_low_wrapper_impl.cpp rename to lib/du/du_low/du_low_wrapper_impl.cpp diff --git a/lib/du_low/du_low_wrapper_impl.h b/lib/du/du_low/du_low_wrapper_impl.h similarity index 95% rename from lib/du_low/du_low_wrapper_impl.h rename to lib/du/du_low/du_low_wrapper_impl.h index ecd883b746..009869f6ba 100644 --- a/lib/du_low/du_low_wrapper_impl.h +++ b/lib/du/du_low/du_low_wrapper_impl.h @@ -10,8 +10,8 @@ #pragma once -#include "srsran/du_low/du_low.h" -#include "srsran/du_low/du_low_wrapper.h" +#include "srsran/du/du_low/du_low.h" +#include "srsran/du/du_low/du_low_wrapper.h" #include "srsran/fapi_adaptor/phy/phy_fapi_adaptor.h" #include #include diff --git a/lib/du/du_update_config_helpers.cpp b/lib/du/du_update_config_helpers.cpp index 8b9364560a..f1d34dbdff 100644 --- a/lib/du/du_update_config_helpers.cpp +++ b/lib/du/du_update_config_helpers.cpp @@ -9,7 +9,7 @@ */ #include "srsran/du/du_update_config_helpers.h" -#include "../du_manager/ran_resource_management/pucch_resource_generator.h" +#include "du_high/du_manager/ran_resource_management/pucch_resource_generator.h" using namespace srsran; diff --git a/lib/du/du_wrapper_factory.cpp b/lib/du/du_wrapper_factory.cpp index b6d14f4f0f..2be897b4aa 100644 --- a/lib/du/du_wrapper_factory.cpp +++ b/lib/du/du_wrapper_factory.cpp @@ -10,8 +10,8 @@ #include "srsran/du/du_wrapper_factory.h" #include "du_wrapper_impl.h" -#include "srsran/du/du_high_wrapper_factory.h" -#include "srsran/du_low/du_low_wrapper_factory.h" +#include "srsran/du/du_high/du_high_wrapper_factory.h" +#include "srsran/du/du_low/du_low_wrapper_factory.h" using namespace srsran; diff --git a/lib/du/du_wrapper_impl.cpp b/lib/du/du_wrapper_impl.cpp index 809ae84751..410cabf2d1 100644 --- a/lib/du/du_wrapper_impl.cpp +++ b/lib/du/du_wrapper_impl.cpp @@ -9,8 +9,8 @@ */ #include "du_wrapper_impl.h" -#include "srsran/du/du_high_wrapper.h" -#include "srsran/du_low/du_low.h" +#include "srsran/du/du_high/du_high_wrapper.h" +#include "srsran/du/du_low/du_low.h" #include "srsran/support/srsran_assert.h" using namespace srsran; diff --git a/lib/du/du_wrapper_impl.h b/lib/du/du_wrapper_impl.h index 7914db66a4..df1be2a1e9 100644 --- a/lib/du/du_wrapper_impl.h +++ b/lib/du/du_wrapper_impl.h @@ -10,9 +10,9 @@ #pragma once -#include "srsran/du/du_high_wrapper.h" +#include "srsran/du/du_high/du_high_wrapper.h" +#include "srsran/du/du_low/du_low_wrapper.h" #include "srsran/du/du_wrapper.h" -#include "srsran/du_low/du_low_wrapper.h" #include "srsran/fapi_adaptor/phy/phy_fapi_adaptor.h" #include diff --git a/lib/du_high/CMakeLists.txt b/lib/du_high/CMakeLists.txt deleted file mode 100644 index 4a22916072..0000000000 --- a/lib/du_high/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright 2021-2024 Software Radio Systems Limited -# -# By using this file, you agree to the terms and conditions set -# forth in the LICENSE file which can be found at the top level of -# the distribution. -# - -add_library(srsran_du_high - du_high_impl.cpp - adapters/mac_test_mode_adapter.cpp - adapters/f1ap_test_mode_adapter.cpp - du_high_factory.cpp) -target_link_libraries(srsran_du_high srslog srsran_support srsran_du_manager srsran_mac srsran_f1ap_du srsran_e2) diff --git a/lib/du_manager/CMakeLists.txt b/lib/du_manager/CMakeLists.txt deleted file mode 100644 index 03fcd105e8..0000000000 --- a/lib/du_manager/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright 2021-2024 Software Radio Systems Limited -# -# By using this file, you agree to the terms and conditions set -# forth in the LICENSE file which can be found at the top level of -# the distribution. -# - -add_subdirectory(ran_resource_management) -add_subdirectory(du_ue) -add_subdirectory(converters) -add_subdirectory(procedures) - -set(SOURCES du_manager_factory.cpp - du_manager_impl.cpp - du_ue/du_ue_manager.cpp - du_cell_manager.cpp) - -add_library(srsran_du_manager STATIC ${SOURCES}) -target_link_libraries(srsran_du_manager - srsran_du_manager_procedures - du_resource_manager - du_ue - du_manager_converters - srsran_du_config_validators - mac_configuration_helpers - srsran_rlc - srsran_f1u_du - srsran_gtpu) diff --git a/lib/e2/common/e2_entity.h b/lib/e2/common/e2_entity.h index a605e981b8..cb561ea915 100644 --- a/lib/e2/common/e2_entity.h +++ b/lib/e2/common/e2_entity.h @@ -14,7 +14,7 @@ #include "procedures/e2_setup_procedure.h" #include "procedures/e2_subscription_setup_procedure.h" #include "srsran/asn1/e2ap/e2ap.h" -#include "srsran/du_manager/du_configurator.h" +#include "srsran/du/du_high/du_manager/du_configurator.h" #include "srsran/e2/e2.h" #include "srsran/e2/e2_connection_client.h" #include "srsran/e2/e2ap_configuration.h" diff --git a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp index d159b8941d..3cba612897 100644 --- a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp +++ b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp @@ -10,6 +10,7 @@ #include "e2sm_rc_control_action_du_executor.h" #include + using namespace asn1::e2ap; using namespace asn1::e2sm; using namespace srsran; diff --git a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h index 2579e0b404..177751b659 100644 --- a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h +++ b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h @@ -12,7 +12,7 @@ #include "srsran/adt/optional.h" #include "srsran/asn1/asn1_utils.h" -#include "srsran/du_manager/du_configurator.h" +#include "srsran/du/du_high/du_manager/du_configurator.h" #include "srsran/e2/e2.h" #include "srsran/e2/e2sm/e2sm.h" #include diff --git a/lib/f1ap/du/f1ap_du_context.h b/lib/f1ap/du/f1ap_du_context.h index dca2dd2233..5138cc32bd 100644 --- a/lib/f1ap/du/f1ap_du_context.h +++ b/lib/f1ap/du/f1ap_du_context.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/adt/slotted_array.h" -#include "srsran/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/ran/gnb_du_id.h" diff --git a/lib/f1ap/du/f1ap_du_factory.cpp b/lib/f1ap/du/f1ap_du_factory.cpp index 63780f69ea..f66ef40145 100644 --- a/lib/f1ap/du/f1ap_du_factory.cpp +++ b/lib/f1ap/du/f1ap_du_factory.cpp @@ -10,7 +10,7 @@ #include "srsran/f1ap/du/f1ap_du_factory.h" #include "f1ap_du_impl.h" -#include "srsran/du_manager/du_manager.h" +#include "srsran/du/du_high/du_manager/du_manager.h" /// Notice this would be the only place were we include concrete class implementation files. diff --git a/lib/f1ap/du/f1ap_du_impl.h b/lib/f1ap/du/f1ap_du_impl.h index e67caa2ee6..978be878f2 100644 --- a/lib/f1ap/du/f1ap_du_impl.h +++ b/lib/f1ap/du/f1ap_du_impl.h @@ -14,7 +14,7 @@ #include "f1ap_du_connection_handler.h" #include "f1ap_du_context.h" #include "srsran/asn1/f1ap/f1ap.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/f1ap/du/f1ap_du.h" #include diff --git a/lib/f1ap/du/ue_context/f1ap_du_ue_manager.h b/lib/f1ap/du/ue_context/f1ap_du_ue_manager.h index bcbb0c99bf..4a881d7541 100644 --- a/lib/f1ap/du/ue_context/f1ap_du_ue_manager.h +++ b/lib/f1ap/du/ue_context/f1ap_du_ue_manager.h @@ -11,7 +11,7 @@ #pragma once #include "f1ap_du_ue.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include #include @@ -114,4 +114,4 @@ class f1ap_du_ue_manager }; } // namespace srs_du -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/mac/mac_ctrl/mac_config.h b/lib/mac/mac_ctrl/mac_config.h index 0a1ea1042d..ad83f396ea 100644 --- a/lib/mac/mac_ctrl/mac_config.h +++ b/lib/mac/mac_ctrl/mac_config.h @@ -11,8 +11,8 @@ #pragma once #include "srsran/adt/span.h" -#include "srsran/du/du_test_config.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_test_mode_config.h" #include "srsran/mac/mac.h" #include "srsran/mac/mac_cell_result.h" #include "srsran/pcap/dlt_pcap.h" diff --git a/lib/mac/mac_dl/mac_dl_ue_repository.h b/lib/mac/mac_dl/mac_dl_ue_repository.h index 18d5fb0c90..466834b8a8 100644 --- a/lib/mac/mac_dl/mac_dl_ue_repository.h +++ b/lib/mac/mac_dl/mac_dl_ue_repository.h @@ -10,8 +10,8 @@ #pragma once +#include "../rnti_value_table.h" #include "cell_dl_harq_buffer_pool.h" -#include "srsran/du_high/rnti_value_table.h" #include "srsran/mac/mac.h" #include "srsran/mac/mac_config.h" #include "srsran/ran/du_types.h" diff --git a/lib/mac/mac_factory.cpp b/lib/mac/mac_factory.cpp index fc853c50ec..b5b5ae268e 100644 --- a/lib/mac/mac_factory.cpp +++ b/lib/mac/mac_factory.cpp @@ -10,7 +10,7 @@ #include "srsran/mac/mac_factory.h" #include "mac_impl.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" using namespace srsran; diff --git a/lib/mac/mac_sched/uci_cell_decoder.h b/lib/mac/mac_sched/uci_cell_decoder.h index 91160351bc..56e95803f7 100644 --- a/lib/mac/mac_sched/uci_cell_decoder.h +++ b/lib/mac/mac_sched/uci_cell_decoder.h @@ -10,8 +10,8 @@ #pragma once +#include "../rnti_value_table.h" #include "rlf_detector.h" -#include "srsran/du_high/rnti_value_table.h" #include "srsran/mac/mac_cell_control_information_handler.h" #include "srsran/ran/csi_report/csi_report_configuration.h" #include "srsran/scheduler/scheduler_configurator.h" diff --git a/lib/mac/mac_ul/mac_ul_processor.h b/lib/mac/mac_ul/mac_ul_processor.h index ac132cda46..403f16c918 100644 --- a/lib/mac/mac_ul/mac_ul_processor.h +++ b/lib/mac/mac_ul/mac_ul_processor.h @@ -13,7 +13,7 @@ #include "../mac_config_interfaces.h" #include "mac_ul_ue_manager.h" #include "pdu_rx_handler.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/mac/mac.h" #include "srsran/mac/mac_config.h" #include "srsran/scheduler/scheduler_feedback_handler.h" diff --git a/lib/mac/mac_ul/mac_ul_ue_manager.h b/lib/mac/mac_ul/mac_ul_ue_manager.h index 8815b6990a..d9e81583a0 100644 --- a/lib/mac/mac_ul/mac_ul_ue_manager.h +++ b/lib/mac/mac_ul/mac_ul_ue_manager.h @@ -10,8 +10,8 @@ #pragma once +#include "../rnti_value_table.h" #include "srsran/adt/slotted_array.h" -#include "srsran/du_high/rnti_value_table.h" #include "srsran/mac/mac.h" #include "srsran/ran/du_types.h" #include "srsran/ran/du_ue_list.h" diff --git a/lib/mac/mac_ul/pdu_rx_handler.h b/lib/mac/mac_ul/pdu_rx_handler.h index 2537ac12ba..1426904665 100644 --- a/lib/mac/mac_ul/pdu_rx_handler.h +++ b/lib/mac/mac_ul/pdu_rx_handler.h @@ -10,13 +10,13 @@ #pragma once +#include "../rnti_value_table.h" #include "mac_scheduler_ce_info_handler.h" #include "mac_ul_sch_pdu.h" #include "mac_ul_ue_manager.h" #include "ul_bsr.h" #include "srsran/adt/slotted_array.h" -#include "srsran/du_high/du_high_executor_mapper.h" -#include "srsran/du_high/rnti_value_table.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/mac/mac.h" #include "srsran/pcap/mac_pcap.h" #include "srsran/ran/du_types.h" diff --git a/lib/mac/rnti_manager.h b/lib/mac/rnti_manager.h index ba64473900..96cbe16ecd 100644 --- a/lib/mac/rnti_manager.h +++ b/lib/mac/rnti_manager.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/du_high/rnti_value_table.h" +#include "rnti_value_table.h" #include "srsran/ran/du_types.h" #include "srsran/ran/rnti.h" diff --git a/include/srsran/du_high/rnti_value_table.h b/lib/mac/rnti_value_table.h similarity index 79% rename from include/srsran/du_high/rnti_value_table.h rename to lib/mac/rnti_value_table.h index c2c3069c68..f5ca7d62a1 100644 --- a/include/srsran/du_high/rnti_value_table.h +++ b/lib/mac/rnti_value_table.h @@ -18,38 +18,53 @@ namespace srsran { -/// \brief Table used by MAC to convert from RNTI to a value in a thread-safe manner. +/// Table used by the MAC layer to convert from RNTI to a value in a thread-safe manner. template class rnti_value_table { + static constexpr rnti_t MIN_CRNTI = rnti_t::MIN_CRNTI; + static constexpr rnti_t MAX_CRNTI = rnti_t::MAX_CRNTI; + static constexpr size_t RNTI_RANGE = to_value(rnti_t::MAX_CRNTI) + 1 - to_value(rnti_t::MIN_CRNTI); + using array_type = std::array, RNTI_RANGE>; + public: rnti_value_table() : rnti_to_ue_index_map(std::make_unique()) { - for (unsigned idx = 0; idx < rnti_to_ue_index_map->size(); ++idx) { - (*rnti_to_ue_index_map)[idx].store(SentinelValue, std::memory_order_relaxed); + for (unsigned i = 0, e = rnti_to_ue_index_map->size(); i != e; ++i) { + (*rnti_to_ue_index_map)[i].store(SentinelValue, std::memory_order_relaxed); } } + rnti_value_table(const rnti_value_table&) = delete; rnti_value_table(rnti_value_table&&) = delete; rnti_value_table& operator=(const rnti_value_table&) = delete; rnti_value_table& operator=(rnti_value_table&&) = delete; + /// \brief Associates the given RNTI to a value. + /// + /// \param crnti RNTI value. + /// \param value Value to associante with an RNTI. + /// \return Returns true if the RNTI does not yet exist, otherwise false. bool add_ue(rnti_t crnti, T value) { srsran_assert(is_crnti(crnti), "Invalid c-rnti={}", crnti); srsran_assert(value != SentinelValue, "Invalid rnti_value_table value={}", value); + std::atomic& ue_pos = get(crnti); T prev_ue_idx = ue_pos.exchange(value, std::memory_order_relaxed); if (prev_ue_idx == SentinelValue) { nof_ues_.fetch_add(1, std::memory_order_relaxed); return true; } + return false; } + /// Removes the given RNTI from the table. void rem_ue(rnti_t crnti) { srsran_assert(is_crnti(crnti), "Invalid c-rnti={}", crnti); + std::atomic& ue_pos = get(crnti); T prev_ue_idx = ue_pos.exchange(SentinelValue, std::memory_order_relaxed); if (prev_ue_idx != SentinelValue) { @@ -61,31 +76,27 @@ class rnti_value_table /// Get an estimate of the current number of UEs present in the table. size_t nof_ues() const { return nof_ues_.load(std::memory_order_relaxed); } - /// Checks whether passed RNTI is registered as a UE. + /// Checks whether the passed RNTI is registered as a UE. bool has_rnti(rnti_t crnti) const { return this->operator[](crnti) != SentinelValue; } T operator[](rnti_t crnti) const { srsran_sanity_check(is_crnti(crnti), "Invalid c-rnti={}", crnti); + const std::atomic& ue_pos = get(crnti); return ue_pos.load(std::memory_order_relaxed); } private: - static constexpr rnti_t MIN_CRNTI = rnti_t::MIN_CRNTI; - static constexpr rnti_t MAX_CRNTI = rnti_t::MAX_CRNTI; - static constexpr int RNTI_RANGE = to_value(rnti_t::MAX_CRNTI) + 1 - to_value(rnti_t::MIN_CRNTI); - using array_type = std::array, RNTI_RANGE>; - std::atomic& get(rnti_t rnti) { return (*rnti_to_ue_index_map)[to_value(rnti) - to_value(rnti_t::MIN_CRNTI)]; } const std::atomic& get(rnti_t rnti) const { return (*rnti_to_ue_index_map)[to_value(rnti) - to_value(rnti_t::MIN_CRNTI)]; } - // Table of RNTI -> UE index with size 65535. + /// Table of RNTI -> UE index with size 65535. std::unique_ptr rnti_to_ue_index_map; - + /// Number of tracked UEs in the table. std::atomic nof_ues_{0}; }; diff --git a/lib/scheduler/config/sched_cell_config_helpers.cpp b/lib/scheduler/config/sched_cell_config_helpers.cpp index da5268f49b..18af5928fa 100644 --- a/lib/scheduler/config/sched_cell_config_helpers.cpp +++ b/lib/scheduler/config/sched_cell_config_helpers.cpp @@ -9,7 +9,7 @@ */ #include "srsran/scheduler/config/sched_cell_config_helpers.h" -#include "../../du_manager/ran_resource_management/pucch_resource_generator.h" +#include "../../du/du_high/du_manager/ran_resource_management/pucch_resource_generator.h" #include "srsran/scheduler/config/serving_cell_config_factory.h" #include "srsran/support/error_handling.h" diff --git a/tests/benchmarks/du_high/du_high_benchmark.cpp b/tests/benchmarks/du_high/du_high_benchmark.cpp index 4011be55e0..5c2efaa0cc 100644 --- a/tests/benchmarks/du_high/du_high_benchmark.cpp +++ b/tests/benchmarks/du_high/du_high_benchmark.cpp @@ -27,8 +27,8 @@ /// which will instantiate 6 threads running in cores 2-7 (assuming du_cell is pinned to 0-1), with high priority /// and a CPU load of 90%. -#include "lib/du_high/du_high_executor_strategies.h" -#include "lib/du_high/du_high_impl.h" +#include "lib/du/du_high/du_high_executor_strategies.h" +#include "lib/du/du_high/du_high_impl.h" #include "lib/mac/mac_ul/ul_bsr.h" #include "tests/test_doubles/f1ap/f1ap_test_messages.h" #include "tests/test_doubles/pdcp/pdcp_pdu_generator.h" @@ -37,8 +37,8 @@ #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" #include "srsran/du/du_cell_config_helpers.h" -#include "srsran/du/du_qos_config_helpers.h" -#include "srsran/du_high/du_high_configuration.h" +#include "srsran/du/du_high/du_high_configuration.h" +#include "srsran/du/du_high/du_qos_config_helpers.h" #include "srsran/f1u/du/f1u_gateway.h" #include "srsran/support/benchmark_utils.h" #include "srsran/support/event_tracing.h" diff --git a/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp b/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp index 39939aff50..8dee40b273 100644 --- a/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp +++ b/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_manager/ran_resource_management/du_pucch_resource_manager.h" +#include "lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.h" #include "scheduler_test_doubles.h" #include "tests/unittests/scheduler/test_utils/config_generators.h" #include "srsran/adt/circular_array.h" diff --git a/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp b/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp index 8da71f6ee1..970a2f96cc 100644 --- a/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp +++ b/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_high/adapters/mac_test_mode_adapter.h" +#include "lib/du/du_high/adapters/mac_test_mode_adapter.h" #include "tests/unittests/mac/mac_test_helpers.h" #include "srsran/ran/csi_report/csi_report_config_helpers.h" #include "srsran/ran/csi_report/csi_report_on_pucch_helpers.h" @@ -105,8 +105,8 @@ class mac_dummy : public mac_interface, }; struct test_params { - unsigned nof_ports; - srs_du::du_test_config::test_ue_config test_ue_cfg; + unsigned nof_ports; + srs_du::du_test_mode_config::test_mode_ue_config test_ue_cfg; }; /// Formatter for test params. diff --git a/tests/integrationtests/du_high/test_utils/du_high_env_simulator.cpp b/tests/integrationtests/du_high/test_utils/du_high_env_simulator.cpp index 34a3143ae2..519bc27cbe 100644 --- a/tests/integrationtests/du_high/test_utils/du_high_env_simulator.cpp +++ b/tests/integrationtests/du_high/test_utils/du_high_env_simulator.cpp @@ -17,8 +17,8 @@ #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" #include "srsran/du/du_cell_config_helpers.h" -#include "srsran/du/du_qos_config_helpers.h" -#include "srsran/du_high/du_high_factory.h" +#include "srsran/du/du_high/du_high_factory.h" +#include "srsran/du/du_high/du_qos_config_helpers.h" #include "srsran/support/error_handling.h" #include "srsran/support/test_utils.h" diff --git a/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h b/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h index b432c98e7d..4d80bc4dad 100644 --- a/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h +++ b/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h @@ -14,8 +14,8 @@ #include "tests/test_doubles/f1u/dummy_f1u_du_gateway.h" #include "tests/test_doubles/mac/dummy_mac_result_notifier.h" #include "tests/test_doubles/mac/mac_test_messages.h" -#include "srsran/du_high/du_high.h" -#include "srsran/du_high/du_high_configuration.h" +#include "srsran/du/du_high/du_high.h" +#include "srsran/du/du_high/du_high_configuration.h" #include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/scheduler/config/cell_config_builder_params.h" diff --git a/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h b/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h index 68a9bfb57e..d8cf99b239 100644 --- a/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h +++ b/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h @@ -10,7 +10,7 @@ #pragma once -#include "lib/du_high/du_high_executor_strategies.h" +#include "lib/du/du_high/du_high_executor_strategies.h" #include "srsran/adt/static_vector.h" #include "srsran/support/executors/manual_task_worker.h" #include "srsran/support/executors/task_worker.h" diff --git a/tests/integrationtests/du_high_cu/cu_du_test.cpp b/tests/integrationtests/du_high_cu/cu_du_test.cpp index af9a2ac004..610bde6289 100644 --- a/tests/integrationtests/du_high_cu/cu_du_test.cpp +++ b/tests/integrationtests/du_high_cu/cu_du_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_high/du_high_executor_strategies.h" +#include "lib/du/du_high/du_high_executor_strategies.h" #include "tests/integrationtests/du_high/test_utils/du_high_worker_manager.h" #include "tests/test_doubles/f1ap/f1c_test_local_gateway.h" #include "tests/unittests/cu_cp/test_doubles/mock_amf.h" @@ -18,7 +18,7 @@ #include "srsran/cu_cp/cu_cp_configuration_helpers.h" #include "srsran/cu_cp/cu_cp_factory.h" #include "srsran/du/du_cell_config_helpers.h" -#include "srsran/du_high/du_high_factory.h" +#include "srsran/du/du_high/du_high_factory.h" #include #include diff --git a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp index 4949bcb4a5..9540c80487 100644 --- a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp +++ b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp @@ -9,14 +9,14 @@ */ #include "du_high_cu_test_simulator.h" -#include "lib/du_high/du_high_executor_strategies.h" +#include "lib/du/du_high/du_high_executor_strategies.h" #include "tests/test_doubles/f1ap/f1ap_test_message_validators.h" #include "tests/test_doubles/mac/mac_test_messages.h" #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/cu_cp/cu_cp_configuration_helpers.h" #include "srsran/cu_cp/cu_cp_factory.h" #include "srsran/du/du_cell_config_helpers.h" -#include "srsran/du_high/du_high_factory.h" +#include "srsran/du/du_high/du_high_factory.h" #include "srsran/support/test_utils.h" #include diff --git a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h index b0c70a74e6..7500dbb2f9 100644 --- a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h +++ b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h @@ -17,8 +17,8 @@ #include "tests/unittests/f1ap/cu_cp/f1ap_cu_test_helpers.h" #include "tests/unittests/ngap/test_helpers.h" #include "srsran/cu_cp/cu_cp.h" -#include "srsran/du_high/du_high.h" -#include "srsran/du_high/du_high_configuration.h" +#include "srsran/du/du_high/du_high.h" +#include "srsran/du/du_high/du_high_configuration.h" #include "srsran/support/executors/manual_task_worker.h" #include "srsran/support/executors/task_worker.h" diff --git a/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h b/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h index 09652e1899..b220617aab 100644 --- a/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h +++ b/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h @@ -10,7 +10,7 @@ #pragma once -#include "../lib/du_manager/ran_resource_management/du_pucch_resource_manager.h" +#include "../lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.h" #include "srsran/du/du_cell_config.h" namespace srsran { diff --git a/tests/unittests/du_manager/du_manager_test_helpers.cpp b/tests/unittests/du_manager/du_manager_test_helpers.cpp index df407f02b7..f91f39bf83 100644 --- a/tests/unittests/du_manager/du_manager_test_helpers.cpp +++ b/tests/unittests/du_manager/du_manager_test_helpers.cpp @@ -10,7 +10,7 @@ #include "du_manager_test_helpers.h" #include "srsran/du/du_cell_config_helpers.h" -#include "srsran/du/du_qos_config_helpers.h" +#include "srsran/du/du_high/du_qos_config_helpers.h" #include "srsran/mac/config/mac_cell_group_config_factory.h" #include "srsran/mac/config/mac_config_helpers.h" #include "srsran/rlc/rlc_srb_config_factory.h" diff --git a/tests/unittests/du_manager/du_manager_test_helpers.h b/tests/unittests/du_manager/du_manager_test_helpers.h index 515f0f5e74..f38e6151b5 100644 --- a/tests/unittests/du_manager/du_manager_test_helpers.h +++ b/tests/unittests/du_manager/du_manager_test_helpers.h @@ -10,8 +10,8 @@ #pragma once -#include "lib/du_manager/ran_resource_management/du_ran_resource_manager.h" -#include "srsran/du_manager/du_manager_params.h" +#include "lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager.h" +#include "srsran/du/du_high/du_manager/du_manager_params.h" #include "srsran/gtpu/gtpu_teid_pool.h" #include "srsran/srslog/srslog.h" #include "srsran/support/async/async_test_utils.h" diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index 5dc52893f7..70aa8b0935 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -8,9 +8,9 @@ * */ -#include "lib/du_manager/ran_resource_management/du_ran_resource_manager_impl.h" +#include "lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h" #include "srsran/du/du_cell_config_helpers.h" -#include "srsran/du/du_qos_config_helpers.h" +#include "srsran/du/du_high/du_qos_config_helpers.h" #include "srsran/support/test_utils.h" #include diff --git a/tests/unittests/du_manager/du_ue/du_bearer_test.cpp b/tests/unittests/du_manager/du_ue/du_bearer_test.cpp index d7eefa2e66..6e0a2b060b 100644 --- a/tests/unittests/du_manager/du_ue/du_bearer_test.cpp +++ b/tests/unittests/du_manager/du_ue/du_bearer_test.cpp @@ -8,8 +8,8 @@ * */ -#include "lib/du_manager/du_ue/du_bearer.h" -#include "lib/du_manager/du_ue/du_ue_bearer_manager.h" +#include "lib/du/du_high/du_manager/du_ue/du_bearer.h" +#include "lib/du/du_high/du_manager/du_ue/du_ue_bearer_manager.h" #include "tests/unittests/du_manager/du_manager_test_helpers.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/support/test_utils.h" diff --git a/tests/unittests/du_manager/du_ue/ue_manager_test.cpp b/tests/unittests/du_manager/du_ue/ue_manager_test.cpp index 85473c5521..b4ecd2f027 100644 --- a/tests/unittests/du_manager/du_ue/ue_manager_test.cpp +++ b/tests/unittests/du_manager/du_ue/ue_manager_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_manager/du_ue/du_ue_manager.h" +#include "lib/du/du_high/du_manager/du_ue/du_ue_manager.h" #include "tests/unittests/du_manager/du_manager_test_helpers.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/support/executors/manual_task_worker.h" diff --git a/tests/unittests/du_manager/mac_cell_group_config_converter_test.cpp b/tests/unittests/du_manager/mac_cell_group_config_converter_test.cpp index 6479cc2ed4..e0c82f9a97 100644 --- a/tests/unittests/du_manager/mac_cell_group_config_converter_test.cpp +++ b/tests/unittests/du_manager/mac_cell_group_config_converter_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_manager/converters/asn1_rrc_config_helpers.h" +#include "lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.h" #include "srsran/asn1/rrc_nr/cell_group_config.h" #include "srsran/mac/config/mac_cell_group_config_factory.h" #include diff --git a/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.cpp b/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.cpp index 4a7bb9d2b7..b2622e2bc7 100644 --- a/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.cpp +++ b/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.cpp @@ -9,8 +9,8 @@ */ #include "du_manager_procedure_test_helpers.h" -#include "lib/du_manager/procedures/ue_configuration_procedure.h" -#include "lib/du_manager/procedures/ue_creation_procedure.h" +#include "lib/du/du_high/du_manager/procedures/ue_configuration_procedure.h" +#include "lib/du/du_high/du_manager/procedures/ue_creation_procedure.h" #include "srsran/rlc/rlc_srb_config_factory.h" #include "srsran/support/test_utils.h" diff --git a/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.h b/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.h index ceaed139d4..f5d5d62f14 100644 --- a/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.h +++ b/tests/unittests/du_manager/procedures/du_manager_procedure_test_helpers.h @@ -11,8 +11,8 @@ #pragma once #include "../du_manager_test_helpers.h" -#include "lib/du_manager/du_ue/du_ue.h" -#include "lib/du_manager/du_ue/du_ue_manager_repository.h" +#include "lib/du/du_high/du_manager/du_ue/du_ue.h" +#include "lib/du/du_high/du_manager/du_ue/du_ue_manager_repository.h" #include "srsran/support/async/fifo_async_task_scheduler.h" namespace srsran { diff --git a/tests/unittests/du_manager/procedures/du_ue_ric_configuration_procedure_test.cpp b/tests/unittests/du_manager/procedures/du_ue_ric_configuration_procedure_test.cpp index 14bacc84d6..3e41a4b253 100644 --- a/tests/unittests/du_manager/procedures/du_ue_ric_configuration_procedure_test.cpp +++ b/tests/unittests/du_manager/procedures/du_ue_ric_configuration_procedure_test.cpp @@ -9,7 +9,7 @@ */ #include "du_manager_procedure_test_helpers.h" -#include "lib/du_manager/procedures/du_ue_ric_configuration_procedure.h" +#include "lib/du/du_high/du_manager/procedures/du_ue_ric_configuration_procedure.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/support/test_utils.h" #include diff --git a/tests/unittests/du_manager/procedures/ue_configuration_test.cpp b/tests/unittests/du_manager/procedures/ue_configuration_test.cpp index b16b4cf85a..765c370233 100644 --- a/tests/unittests/du_manager/procedures/ue_configuration_test.cpp +++ b/tests/unittests/du_manager/procedures/ue_configuration_test.cpp @@ -12,7 +12,7 @@ /// \brief Unit tests for the DU UE configuration procedure. #include "du_manager_procedure_test_helpers.h" -#include "lib/du_manager/procedures/ue_configuration_procedure.h" +#include "lib/du/du_high/du_manager/procedures/ue_configuration_procedure.h" #include "tests/test_doubles/pdcp/pdcp_pdu_generator.h" #include "srsran/asn1/rrc_nr/cell_group_config.h" #include "srsran/du/du_cell_config_helpers.h" diff --git a/tests/unittests/du_manager/procedures/ue_creation_test.cpp b/tests/unittests/du_manager/procedures/ue_creation_test.cpp index fedfadc009..a178146237 100644 --- a/tests/unittests/du_manager/procedures/ue_creation_test.cpp +++ b/tests/unittests/du_manager/procedures/ue_creation_test.cpp @@ -9,7 +9,7 @@ */ #include "du_manager_procedure_test_helpers.h" -#include "lib/du_manager/procedures/ue_creation_procedure.h" +#include "lib/du/du_high/du_manager/procedures/ue_creation_procedure.h" #include "srsran/asn1/rrc_nr/cell_group_config.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/support/test_utils.h" diff --git a/tests/unittests/du_manager/procedures/ue_deletion_test.cpp b/tests/unittests/du_manager/procedures/ue_deletion_test.cpp index adf0fe273b..22006f9adc 100644 --- a/tests/unittests/du_manager/procedures/ue_deletion_test.cpp +++ b/tests/unittests/du_manager/procedures/ue_deletion_test.cpp @@ -8,8 +8,8 @@ * */ #include "du_manager_procedure_test_helpers.h" -#include "lib/du_manager/procedures/ue_creation_procedure.h" -#include "lib/du_manager/procedures/ue_deletion_procedure.h" +#include "lib/du/du_high/du_manager/procedures/ue_creation_procedure.h" +#include "lib/du/du_high/du_manager/procedures/ue_deletion_procedure.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/support/test_utils.h" #include diff --git a/tests/unittests/du_manager/pucch_resource_generator_test.cpp b/tests/unittests/du_manager/pucch_resource_generator_test.cpp index 7e2d94e2c6..cac097b199 100644 --- a/tests/unittests/du_manager/pucch_resource_generator_test.cpp +++ b/tests/unittests/du_manager/pucch_resource_generator_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_manager/ran_resource_management/pucch_resource_generator.h" +#include "lib/du/du_high/du_manager/ran_resource_management/pucch_resource_generator.h" #include "tests/unittests/scheduler/test_utils/config_generators.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/support/test_utils.h" diff --git a/tests/unittests/du_manager/serving_cell_config_converter_test.cpp b/tests/unittests/du_manager/serving_cell_config_converter_test.cpp index 7efc5dd72f..55e78fddd2 100644 --- a/tests/unittests/du_manager/serving_cell_config_converter_test.cpp +++ b/tests/unittests/du_manager/serving_cell_config_converter_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_manager/converters/asn1_rrc_config_helpers.h" +#include "lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.h" #include "srsran/asn1/asn1_utils.h" #include "srsran/asn1/rrc_nr/cell_group_config.h" #include "srsran/mac/config/mac_cell_group_config_factory.h" diff --git a/tests/unittests/du_manager/sib_test.cpp b/tests/unittests/du_manager/sib_test.cpp index de92466ab6..7052c938c6 100644 --- a/tests/unittests/du_manager/sib_test.cpp +++ b/tests/unittests/du_manager/sib_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_manager/converters/f1ap_configuration_helpers.h" +#include "lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h" #include "srsran/asn1/rrc_nr/sys_info.h" #include "srsran/ran/sib/system_info_config.h" #include diff --git a/tests/unittests/f1ap/du/f1ap_du_test_helpers.h b/tests/unittests/f1ap/du/f1ap_du_test_helpers.h index 025f022c46..8000ad4f09 100644 --- a/tests/unittests/f1ap/du/f1ap_du_test_helpers.h +++ b/tests/unittests/f1ap/du/f1ap_du_test_helpers.h @@ -10,7 +10,7 @@ #pragma once -#include "lib/du_manager/converters/f1ap_configuration_helpers.h" +#include "lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h" #include "srsran/adt/slotted_array.h" #include "srsran/asn1/f1ap/f1ap_ies.h" #include "srsran/f1ap/common/f1ap_common.h" diff --git a/tests/unittests/mac/mac_ctrl_test_dummies.h b/tests/unittests/mac/mac_ctrl_test_dummies.h index 5e90b8ff18..fb32f57189 100644 --- a/tests/unittests/mac/mac_ctrl_test_dummies.h +++ b/tests/unittests/mac/mac_ctrl_test_dummies.h @@ -13,7 +13,7 @@ #include "lib/mac/mac_config_interfaces.h" #include "lib/mac/mac_ctrl/mac_scheduler_configurator.h" #include "srsran/adt/optional.h" -#include "srsran/du_high/du_high_executor_mapper.h" +#include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/mac/mac_cell_result.h" #include "srsran/pcap/dlt_pcap.h" #include "srsran/scheduler/scheduler_metrics.h" diff --git a/tests/unittests/scheduler/test_utils/config_generators.h b/tests/unittests/scheduler/test_utils/config_generators.h index 4bf139d54c..4027570ceb 100644 --- a/tests/unittests/scheduler/test_utils/config_generators.h +++ b/tests/unittests/scheduler/test_utils/config_generators.h @@ -10,7 +10,7 @@ #pragma once -#include "lib/du_manager/converters/scheduler_configuration_helpers.h" +#include "lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h" #include "lib/scheduler/config/sched_config_manager.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/ran/duplex_mode.h" diff --git a/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp b/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp index 7e20f4cc09..a8c33137df 100644 --- a/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp +++ b/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/du_manager/ran_resource_management/pucch_resource_generator.h" +#include "lib/du/du_high/du_manager/ran_resource_management/pucch_resource_generator.h" #include "tests/unittests/scheduler/test_utils/scheduler_test_suite.h" #include "uci_test_utils.h" #include From 46c883178426b8bf9876ba62fb291d3696de6d1b Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 9 Sep 2024 13:51:25 +0200 Subject: [PATCH 006/174] Fix include path to be relative to srsran --- include/srsran/e1ap/cu_cp/e1ap_cu_cp_bearer_context_update.h | 2 +- include/srsran/e1ap/cu_up/e1ap_cu_up.h | 2 +- include/srsran/e1ap/cu_up/e1ap_cu_up_bearer_context_update.h | 2 +- include/srsran/f1ap/cu_cp/f1ap_cu.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/srsran/e1ap/cu_cp/e1ap_cu_cp_bearer_context_update.h b/include/srsran/e1ap/cu_cp/e1ap_cu_cp_bearer_context_update.h index 90f520e04b..016ca83c75 100644 --- a/include/srsran/e1ap/cu_cp/e1ap_cu_cp_bearer_context_update.h +++ b/include/srsran/e1ap/cu_cp/e1ap_cu_cp_bearer_context_update.h @@ -10,8 +10,8 @@ #pragma once -#include "../common/e1ap_types.h" #include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/e1ap/common/e1ap_types.h" namespace srsran { namespace srs_cu_cp { diff --git a/include/srsran/e1ap/cu_up/e1ap_cu_up.h b/include/srsran/e1ap/cu_up/e1ap_cu_up.h index 4054e9b1bc..90038f0bed 100644 --- a/include/srsran/e1ap/cu_up/e1ap_cu_up.h +++ b/include/srsran/e1ap/cu_up/e1ap_cu_up.h @@ -10,12 +10,12 @@ #pragma once -#include "../common/e1ap_types.h" #include "e1ap_cu_up_bearer_context_update.h" #include "srsran/adt/expected.h" #include "srsran/cu_up/cu_up_types.h" #include "srsran/e1ap/common/e1_setup_messages.h" #include "srsran/e1ap/common/e1ap_common.h" +#include "srsran/e1ap/common/e1ap_types.h" #include "srsran/support/async/async_task.h" namespace srsran { diff --git a/include/srsran/e1ap/cu_up/e1ap_cu_up_bearer_context_update.h b/include/srsran/e1ap/cu_up/e1ap_cu_up_bearer_context_update.h index 982c43dc83..ff63b67c8a 100644 --- a/include/srsran/e1ap/cu_up/e1ap_cu_up_bearer_context_update.h +++ b/include/srsran/e1ap/cu_up/e1ap_cu_up_bearer_context_update.h @@ -10,8 +10,8 @@ #pragma once -#include "../common/e1ap_types.h" #include "srsran/cu_up/cu_up_types.h" +#include "srsran/e1ap/common/e1ap_types.h" namespace srsran { namespace srs_cu_up { diff --git a/include/srsran/f1ap/cu_cp/f1ap_cu.h b/include/srsran/f1ap/cu_cp/f1ap_cu.h index 7be1e1b5c8..3eff15b5d8 100644 --- a/include/srsran/f1ap/cu_cp/f1ap_cu.h +++ b/include/srsran/f1ap/cu_cp/f1ap_cu.h @@ -10,7 +10,6 @@ #pragma once -#include "../common/f1ap_ue_id.h" #include "du_setup_notifier.h" #include "f1ap_cu_ue_context_update.h" #include "srsran/adt/byte_buffer.h" @@ -18,6 +17,7 @@ #include "srsran/cu_cp/cu_cp_types.h" #include "srsran/cu_cp/cu_cp_ue_messages.h" #include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/cu_cp/f1ap_du_context.h" #include "srsran/ran/lcid.h" #include "srsran/support/async/async_task.h" From 73ba11509acd107690c186a1ae34dd71e5c5f9ee Mon Sep 17 00:00:00 2001 From: asaezper Date: Tue, 10 Sep 2024 16:21:56 +0200 Subject: [PATCH 007/174] gitlab: add an issue template --- .gitlab/issue_templates/triage.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .gitlab/issue_templates/triage.md diff --git a/.gitlab/issue_templates/triage.md b/.gitlab/issue_templates/triage.md new file mode 100644 index 0000000000..c16b7dd9a3 --- /dev/null +++ b/.gitlab/issue_templates/triage.md @@ -0,0 +1,16 @@ +## Summary + +(Summarize the bug encountered concisely) + +## Relevant logs and/or screenshots + +(Paste any relevant logs - use code blocks (```) to format console output, logs, and code, as +it's very hard to read otherwise.) + +## CI Links + +- Add a link to each job that has this failure. Please press `Keep artifacts` to save the job's data as much as possible. + + +/label ~bug::ci ~triage +/assign @Falkenber9 @supreeth.herle @piotr.gawlowicz From f03a797740470122b61915402b67b4661aa94179 Mon Sep 17 00:00:00 2001 From: dvdgrgrtt Date: Wed, 4 Sep 2024 18:19:15 +0200 Subject: [PATCH 008/174] phy: refactor pucch format 0 validator Return an error_type instead of a simple bool. --- .../channel_processors/pucch_processor.h | 8 +- .../channel_processor_factories.cpp | 3 +- .../pucch_processor_impl.cpp | 121 +++++++----------- .../channel_processors/pucch_processor_impl.h | 19 +-- lib/phy/upper/upper_phy_pdu_validators.h | 5 +- ...pucch_processor_validator_format0_test.cpp | 11 +- 6 files changed, 76 insertions(+), 91 deletions(-) diff --git a/include/srsran/phy/upper/channel_processors/pucch_processor.h b/include/srsran/phy/upper/channel_processors/pucch_processor.h index da5ff61318..07376ed7d9 100644 --- a/include/srsran/phy/upper/channel_processors/pucch_processor.h +++ b/include/srsran/phy/upper/channel_processors/pucch_processor.h @@ -10,14 +10,12 @@ #pragma once -#include "srsran/adt/optional.h" +#include "srsran/adt/expected.h" #include "srsran/adt/static_vector.h" #include "srsran/phy/constants.h" #include "srsran/phy/upper/channel_processors/pucch_processor_result.h" -#include "srsran/phy/upper/channel_processors/pucch_uci_message.h" #include "srsran/ran/cyclic_prefix.h" #include "srsran/ran/pucch/pucch_context.h" -#include "srsran/ran/sch/modulation_scheme.h" #include "srsran/ran/slot_point.h" namespace srsran { @@ -232,8 +230,8 @@ class pucch_pdu_validator virtual ~pucch_pdu_validator() = default; /// \brief Validates PUCCH Format 0 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format0_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format0_configuration& config) const = 0; /// \brief Validates PUCCH Format 1 configuration parameters. /// \return True if the parameters contained in \c config are supported, false otherwise. diff --git a/lib/phy/upper/channel_processors/channel_processor_factories.cpp b/lib/phy/upper/channel_processors/channel_processor_factories.cpp index 7d0b2fdee0..1e5c658d07 100644 --- a/lib/phy/upper/channel_processors/channel_processor_factories.cpp +++ b/lib/phy/upper/channel_processors/channel_processor_factories.cpp @@ -703,7 +703,8 @@ class pucch_processor_factory_sw : public pucch_processor_factory std::unique_ptr create() override { - return std::make_unique(dmrs_factory->create_format1(), + return std::make_unique(create_validator(), + dmrs_factory->create_format1(), dmrs_factory->create_format2(), detector_factory->create(), demodulator_factory->create(), diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp index 38c78914a5..526b0349a4 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp @@ -9,18 +9,32 @@ */ #include "pucch_processor_impl.h" +#include "srsran/adt/expected.h" #include "srsran/ran/pucch/pucch_constants.h" #include "srsran/ran/pucch/pucch_info.h" #include "srsran/support/transform_optional.h" +#include "fmt/core.h" #include #include using namespace srsran; +/// Looks at the output of the validator and, if unsuccessful, fills msg with the error message. +/// This is used to call the validator inside the process methods only if asserts are active. +[[maybe_unused]] static bool handle_validation(std::string& msg, const error_type& err) +{ + bool is_success = err.has_value(); + if (!is_success) { + msg = err.error(); + } + return is_success; +} + pucch_processor_result pucch_processor_impl::process(const resource_grid_reader& grid, const pucch_processor::format0_configuration& config) { - assert_format0_config(config); + [[maybe_unused]] std::string msg; + srsran_assert(handle_validation(msg, pdu_validator->is_valid(config)), "{}", msg); // Calculate actual PRB. std::optional second_hop_prb; @@ -253,66 +267,6 @@ void pucch_processor_impl::assert_format1_config(const pucch_processor::format1_ max_sizes.nof_rx_ports); } -void pucch_processor_impl::assert_format0_config(const pucch_processor::format0_configuration& config) -{ - // Assert BWP allocation. - srsran_assert(config.bwp_start_rb + config.bwp_size_rb <= MAX_RB, - "BWP allocation goes up to PRB {}, exceeding the configured maximum grid RB size, i.e., {}.", - config.bwp_start_rb + config.bwp_size_rb, - MAX_RB); - - // Assert that the PRB allocation is constrained to the BWP. Recall that PUCCH Format 0 occupies a single PRB. - srsran_assert(config.starting_prb < config.bwp_size_rb, - "PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", - config.starting_prb + 1, - config.bwp_size_rb); - - if (config.second_hop_prb.has_value()) { - srsran_assert(config.second_hop_prb.value() < config.bwp_size_rb, - "Second hop PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", - config.second_hop_prb.value() + 1, - config.bwp_size_rb); - } - - // Assert that the OFDM symbols are constrained to the slot dimensions given by the CP. - srsran_assert(config.start_symbol_index + config.nof_symbols <= get_nsymb_per_slot(config.cp), - "OFDM symbol allocation goes up to symbol {}, exceeding the number of symbols in the given slot with " - "{} CP, i.e., {}.", - config.start_symbol_index + config.nof_symbols, - config.cp.to_string(), - get_nsymb_per_slot(config.cp)); - - // Assert that the OFDM symbols are within the configured maximum slot dimensions. - srsran_assert(pucch_constants::format0_nof_symbols_range.contains(config.nof_symbols), - "Number of symbols (i.e., {}) is out of the range {}.", - config.nof_symbols, - pucch_constants::format0_nof_symbols_range); - - // Assert that initial cyclic shift is within the valid range. - srsran_assert(pucch_constants::format0_initial_cyclic_shift_range.contains(config.initial_cyclic_shift), - "The initial cyclic shift (i.e., {}) is out of the range {}.", - config.initial_cyclic_shift, - pucch_constants::format0_initial_cyclic_shift_range); - - // Assert that the sequence hopping identifier is within the valid range. - srsran_assert(pucch_constants::n_id_range.contains(config.n_id), - "The sequence hopping identifier (i.e., {}) is out of the range {}.", - config.n_id, - pucch_constants::n_id_range); - - // Assert that the number of HARQ-ACK bits is within the valid range. - srsran_assert(pucch_constants::format0_nof_harq_ack_range.contains(config.nof_harq_ack), - "The number of HARQ-ACK bits (i.e., {}) is out of the range {}.", - config.nof_harq_ack, - pucch_constants::format0_nof_harq_ack_range); - - // Assert that there is payload. - srsran_assert(config.sr_opportunity || (config.nof_harq_ack > 0), "No payload."); - - // Assert the number of receive ports. - srsran_assert(!config.ports.empty(), "The number of receive ports cannot be zero."); -} - void pucch_processor_impl::assert_format2_config(const pucch_processor::format2_configuration& config) { // Assert BWP allocation. @@ -372,61 +326,82 @@ void pucch_processor_impl::assert_format2_config(const pucch_processor::format2_ static_cast(FORMAT2_MAX_UCI_NBITS)); } -bool pucch_pdu_validator_impl::is_valid(const pucch_processor::format0_configuration& config) const +error_type pucch_pdu_validator_impl::is_valid(const pucch_processor::format0_configuration& config) const { // BWP PRB shall not exceed the maximum. if (config.bwp_start_rb + config.bwp_size_rb > MAX_RB) { - return false; + return make_unexpected( + fmt::format("BWP allocation goes up to PRB {}, exceeding the configured maximum grid RB size, i.e., {}.", + config.bwp_start_rb + config.bwp_size_rb, + MAX_RB)); } // PRB allocation goes beyond the BWP. Recall that PUCCH Format 0 occupies a single PRB. if (config.starting_prb >= config.bwp_size_rb) { - return false; + return make_unexpected(fmt::format("PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", + config.starting_prb + 1, + config.bwp_size_rb)); } // Second hop PRB allocation goes beyond the BWP. if (config.second_hop_prb.has_value()) { if (config.second_hop_prb.value() >= config.bwp_size_rb) { - return false; + return make_unexpected( + fmt::format("Second hop PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", + config.second_hop_prb.value() + 1, + config.bwp_size_rb)); } } // The number of symbols shall be in the range. if (!pucch_constants::format0_nof_symbols_range.contains(config.nof_symbols)) { - return false; + return make_unexpected(fmt::format("Number of symbols (i.e., {}) is out of the range {}.", + config.nof_symbols, + pucch_constants::format0_nof_symbols_range)); } // None of the occupied symbols can exceed the configured maximum slot size, or the slot size given by the CP. if (config.start_symbol_index + config.nof_symbols > get_nsymb_per_slot(config.cp)) { - return false; + return make_unexpected(fmt::format( + "OFDM symbol allocation goes up to symbol {}, exceeding the number of symbols in the given slot with " + "{} CP, i.e., {}.", + config.start_symbol_index + config.nof_symbols, + config.cp.to_string(), + get_nsymb_per_slot(config.cp))); } // Initial cyclic shift must be in range. if (!pucch_constants::format0_initial_cyclic_shift_range.contains(config.initial_cyclic_shift)) { - return false; + return make_unexpected(fmt::format("The initial cyclic shift (i.e., {}) is out of the range {}.", + config.initial_cyclic_shift, + pucch_constants::format0_initial_cyclic_shift_range)); } // Hopping identifier must be in range. if (!pucch_constants::n_id_range.contains(config.n_id)) { - return false; + return make_unexpected(fmt::format("The sequence hopping identifier (i.e., {}) is out of the range {}.", + config.n_id, + pucch_constants::n_id_range)); } // No payload detected. if ((config.nof_harq_ack == 0) && !config.sr_opportunity) { - return false; + return make_unexpected(fmt::format("No payload.")); } // Number of HARQ-ACK exceeds maximum. if (!pucch_constants::format0_nof_harq_ack_range.contains(config.nof_harq_ack)) { - return false; + return make_unexpected(fmt::format("The number of HARQ-ACK bits (i.e., {}) is out of the range {}.", + config.nof_harq_ack, + pucch_constants::format0_nof_harq_ack_range)); } // The number of receive ports must not be empty. if (config.ports.empty()) { - return false; + return make_unexpected(fmt::format("The number of receive ports cannot be zero.")); } - return true; + return default_success_t(); } bool pucch_pdu_validator_impl::is_valid(const pucch_processor::format1_configuration& config) const diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.h b/lib/phy/upper/channel_processors/pucch_processor_impl.h index 8912e3f72c..8c69aa6e5c 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.h +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.h @@ -10,6 +10,7 @@ #pragma once +#include "srsran/adt/expected.h" #include "srsran/phy/upper/channel_processors/pucch_demodulator.h" #include "srsran/phy/upper/channel_processors/pucch_detector.h" #include "srsran/phy/upper/channel_processors/pucch_processor.h" @@ -35,11 +36,11 @@ class pucch_pdu_validator_impl : public pucch_pdu_validator } // See interface for documentation. - bool is_valid(const pucch_processor::format0_configuration& config) const override; - bool is_valid(const pucch_processor::format1_configuration& config) const override; - bool is_valid(const pucch_processor::format2_configuration& config) const override; - bool is_valid(const pucch_processor::format3_configuration& config) const override { return true; } - bool is_valid(const pucch_processor::format4_configuration& config) const override { return true; } + error_type is_valid(const pucch_processor::format0_configuration& config) const override; + bool is_valid(const pucch_processor::format1_configuration& config) const override; + bool is_valid(const pucch_processor::format2_configuration& config) const override; + bool is_valid(const pucch_processor::format3_configuration& config) const override { return true; } + bool is_valid(const pucch_processor::format4_configuration& config) const override { return true; } private: /// Maximum transmit and receive resource grid dimensions handled by the PUCCH processor. @@ -77,12 +78,14 @@ class pucch_processor_impl : public pucch_processor } /// PUCCH processor constructor. - pucch_processor_impl(std::unique_ptr channel_estimator_format_1_, + pucch_processor_impl(std::unique_ptr pdu_validator_, + std::unique_ptr channel_estimator_format_1_, std::unique_ptr channel_estimator_format_2_, std::unique_ptr detector_, std::unique_ptr demodulator_, std::unique_ptr decoder_, const channel_estimate::channel_estimate_dimensions& estimates_dimensions) : + pdu_validator(std::move(pdu_validator_)), channel_estimator_format_1(std::move(channel_estimator_format_1_)), channel_estimator_format_2(std::move(channel_estimator_format_2_)), detector(std::move(detector_)), @@ -99,13 +102,13 @@ class pucch_processor_impl : public pucch_processor } private: - /// Validates PUCCH Format 0 configuration. - void assert_format0_config(const pucch_processor::format0_configuration& config); /// Validates PUCCH Format 1 configuration. void assert_format1_config(const pucch_processor::format1_configuration& config); /// Validates PUCCH Format 2 configuration. void assert_format2_config(const pucch_processor::format2_configuration& config); + /// PUCCH PDU validator for all formats. + std::unique_ptr pdu_validator; /// Channel estimator for PUCCH Format 1. std::unique_ptr channel_estimator_format_1; /// Channel estimator for PUCCH Format 2. diff --git a/lib/phy/upper/upper_phy_pdu_validators.h b/lib/phy/upper/upper_phy_pdu_validators.h index 0147e0ace1..8542a5ccc2 100644 --- a/lib/phy/upper/upper_phy_pdu_validators.h +++ b/lib/phy/upper/upper_phy_pdu_validators.h @@ -35,7 +35,10 @@ class uplink_processor_validator_impl : public uplink_pdu_validator // See interface for documentation. bool is_valid(const prach_detector::configuration& config) const override { return prach->is_valid(config); } - bool is_valid(const pucch_processor::format0_configuration& config) const override { return pucch->is_valid(config); } + bool is_valid(const pucch_processor::format0_configuration& config) const override + { + return pucch->is_valid(config).has_value(); + } bool is_valid(const pucch_processor::format1_configuration& config) const override { return pucch->is_valid(config); } bool is_valid(const pucch_processor::format2_configuration& config) const override { return pucch->is_valid(config); } bool is_valid(const pucch_processor::format3_configuration& config) const override { return pucch->is_valid(config); } diff --git a/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format0_test.cpp b/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format0_test.cpp index 4c33b18490..648cdda4c3 100644 --- a/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format0_test.cpp +++ b/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format0_test.cpp @@ -9,19 +9,21 @@ */ #include "../../support/resource_grid_test_doubles.h" +#include "srsran/adt/expected.h" #include "srsran/phy/upper/channel_processors/channel_processor_factories.h" #include "srsran/phy/upper/channel_processors/channel_processor_formatters.h" #include "srsran/phy/upper/equalization/equalization_factories.h" #include "srsran/ran/pucch/pucch_constants.h" #include "fmt/ostream.h" -#include "gtest/gtest.h" +#include +#include using namespace srsran; namespace { // Maximum channel dimensions used to construct the PUCCH processor. It is irrelevant for Format 0. -static channel_estimate::channel_estimate_dimensions max_dimensions = {1, 1, 1, 1}; +channel_estimate::channel_estimate_dimensions max_dimensions = {1, 1, 1, 1}; // Valid PUCCH Format 0 configuration. const pucch_processor::format0_configuration base_format_0_config = { @@ -286,7 +288,10 @@ TEST_P(PucchProcessorFormat0Fixture, PucchProcessorValidatortest) const test_case_t& param = GetParam(); // Make sure the configuration is invalid. - ASSERT_FALSE(pucch_validator->is_valid(param.get_test_params().config)); + error_type validator_out = pucch_validator->is_valid(param.get_test_params().config); + ASSERT_FALSE(validator_out.has_value()) << "Validation should fail."; + ASSERT_TRUE(std::regex_match(validator_out.error(), std::regex(param.get_test_params().assert_message))) + << "The assertion message doesn't match the expected pattern."; // Prepare resource grid. resource_grid_reader_spy grid; From 869cb1a23be3bf700f1ff700b7590eaabb334850 Mon Sep 17 00:00:00 2001 From: dvdgrgrtt Date: Fri, 6 Sep 2024 08:15:44 +0200 Subject: [PATCH 009/174] phy: refactor pucch format 1 validator Return an error_type instead of a simple bool. --- .../channel_processors/pucch_processor.h | 4 +- .../pucch_processor_impl.cpp | 94 +++++++------------ .../channel_processors/pucch_processor_impl.h | 8 +- lib/phy/upper/upper_phy_pdu_validators.h | 5 +- ...pucch_processor_validator_format1_test.cpp | 16 ++-- 5 files changed, 55 insertions(+), 72 deletions(-) diff --git a/include/srsran/phy/upper/channel_processors/pucch_processor.h b/include/srsran/phy/upper/channel_processors/pucch_processor.h index 07376ed7d9..239d9f4acc 100644 --- a/include/srsran/phy/upper/channel_processors/pucch_processor.h +++ b/include/srsran/phy/upper/channel_processors/pucch_processor.h @@ -234,8 +234,8 @@ class pucch_pdu_validator virtual error_type is_valid(const pucch_processor::format0_configuration& config) const = 0; /// \brief Validates PUCCH Format 1 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format1_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format1_configuration& config) const = 0; /// \brief Validates PUCCH Format 2 configuration parameters. /// \return True if the parameters contained in \c config are supported, false otherwise. diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp index 526b0349a4..742172bb7c 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp @@ -65,8 +65,8 @@ pucch_processor_result pucch_processor_impl::process(const resource_grid_reader& pucch_processor_result pucch_processor_impl::process(const resource_grid_reader& grid, const format1_configuration& config) { - // Check that the PUCCH Format 1 configuration is valid. - assert_format1_config(config); + [[maybe_unused]] std::string msg; + srsran_assert(handle_validation(msg, pdu_validator->is_valid(config)), "{}", msg); // Prepare channel estimation. dmrs_pucch_processor::config_t estimator_config; @@ -221,52 +221,6 @@ pucch_processor_result pucch_processor_impl::process(const resource_grid_reader& return result; } -void pucch_processor_impl::assert_format1_config(const pucch_processor::format1_configuration& config) -{ - // Assert BWP allocation. - srsran_assert(config.bwp_start_rb + config.bwp_size_rb <= max_sizes.nof_prb, - "BWP allocation goes up to PRB {}, exceeding the configured maximum grid RB size, i.e., {}.", - config.bwp_start_rb + config.bwp_size_rb, - max_sizes.nof_prb); - - // Assert that the PRB allocation is constrained to the BWP. Recall that PUCCH Format 1 occupies a single PRB. - srsran_assert(config.starting_prb < config.bwp_size_rb, - "PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", - config.starting_prb + 1, - config.bwp_size_rb); - - if (config.second_hop_prb.has_value()) { - srsran_assert(config.second_hop_prb.value() < config.bwp_size_rb, - "Second hop PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", - config.second_hop_prb.value() + 1, - config.bwp_size_rb); - } - - // Assert that the OFDM symbols are constrained to the slot dimensions given by the CP. - srsran_assert(config.start_symbol_index + config.nof_symbols <= get_nsymb_per_slot(config.cp), - "OFDM symbol allocation goes up to symbol {}, exceeding the number of symbols in the given slot with " - "{} CP, i.e., {}.", - config.start_symbol_index + config.nof_symbols, - config.cp.to_string(), - get_nsymb_per_slot(config.cp)); - - // Assert that the OFDM symbols are within the configured maximum slot dimensions. - srsran_assert( - config.start_symbol_index + config.nof_symbols <= max_sizes.nof_symbols, - "OFDM symbol allocation goes up to symbol {}, exceeding the configured maximum number of slot symbols, i.e., {}.", - config.start_symbol_index + config.nof_symbols, - max_sizes.nof_symbols); - - // Assert the number of receive ports. - srsran_assert(!config.ports.empty(), "The number of receive ports cannot be zero."); - - srsran_assert( - config.ports.size() <= max_sizes.nof_rx_ports, - "The number of receive ports, i.e. {}, exceeds the configured maximum number of receive ports, i.e., {}.", - config.ports.size(), - max_sizes.nof_rx_ports); -} - void pucch_processor_impl::assert_format2_config(const pucch_processor::format2_configuration& config) { // Assert BWP allocation. @@ -404,37 +358,61 @@ error_type pucch_pdu_validator_impl::is_valid(const pucch_processor return default_success_t(); } -bool pucch_pdu_validator_impl::is_valid(const pucch_processor::format1_configuration& config) const +error_type pucch_pdu_validator_impl::is_valid(const pucch_processor::format1_configuration& config) const { // The BWP size exceeds the grid dimensions. if ((config.bwp_start_rb + config.bwp_size_rb) > ce_dims.nof_prb) { - return false; + return make_unexpected( + fmt::format("BWP allocation goes up to PRB {}, exceeding the configured maximum grid RB size, i.e., {}.", + config.bwp_start_rb + config.bwp_size_rb, + ce_dims.nof_prb)); } // PRB allocation goes beyond the BWP. Recall that PUCCH Format 1 occupies a single PRB. if (config.starting_prb >= config.bwp_size_rb) { - return false; + return make_unexpected(fmt::format("PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", + config.starting_prb + 1, + config.bwp_size_rb)); } // Second hop PRB allocation goes beyond the BWP. if (config.second_hop_prb.has_value()) { if (config.second_hop_prb.value() >= config.bwp_size_rb) { - return false; + return make_unexpected( + fmt::format("Second hop PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", + config.second_hop_prb.value() + 1, + config.bwp_size_rb)); } } // None of the occupied symbols can exceed the configured maximum slot size, or the slot size given by the CP. - if ((config.start_symbol_index + config.nof_symbols > get_nsymb_per_slot(config.cp)) || - (config.start_symbol_index + config.nof_symbols > ce_dims.nof_symbols)) { - return false; + if (config.start_symbol_index + config.nof_symbols > get_nsymb_per_slot(config.cp)) { + return make_unexpected(fmt::format( + "OFDM symbol allocation goes up to symbol {}, exceeding the number of symbols in the given slot with " + "{} CP, i.e., {}.", + config.start_symbol_index + config.nof_symbols, + config.cp.to_string(), + get_nsymb_per_slot(config.cp))); + } + if (config.start_symbol_index + config.nof_symbols > ce_dims.nof_symbols) { + return make_unexpected(fmt::format("OFDM symbol allocation goes up to symbol {}, exceeding the configured maximum " + "number of slot symbols, i.e., {}.", + config.start_symbol_index + config.nof_symbols, + ce_dims.nof_symbols)); } // The number of receive ports is either zero or exceeds the configured maximum number of receive ports. - if (config.ports.empty() || (config.ports.size() > ce_dims.nof_rx_ports)) { - return false; + if (config.ports.empty()) { + return make_unexpected(fmt::format("The number of receive ports cannot be zero.")); + } + if (config.ports.size() > ce_dims.nof_rx_ports) { + return make_unexpected(fmt::format( + "The number of receive ports, i.e. {}, exceeds the configured maximum number of receive ports, i.e., {}.", + config.ports.size(), + ce_dims.nof_rx_ports)); } - return true; + return default_success_t(); } bool pucch_pdu_validator_impl::is_valid(const pucch_processor::format2_configuration& config) const diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.h b/lib/phy/upper/channel_processors/pucch_processor_impl.h index 8c69aa6e5c..3db06aaaf5 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.h +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.h @@ -37,7 +37,7 @@ class pucch_pdu_validator_impl : public pucch_pdu_validator // See interface for documentation. error_type is_valid(const pucch_processor::format0_configuration& config) const override; - bool is_valid(const pucch_processor::format1_configuration& config) const override; + error_type is_valid(const pucch_processor::format1_configuration& config) const override; bool is_valid(const pucch_processor::format2_configuration& config) const override; bool is_valid(const pucch_processor::format3_configuration& config) const override { return true; } bool is_valid(const pucch_processor::format4_configuration& config) const override { return true; } @@ -67,14 +67,14 @@ class pucch_processor_impl : public pucch_processor pucch_processor_result process(const resource_grid_reader& grid, const format3_configuration& config) override { // TBD. - return pucch_processor_result(); + return {}; } // See interface for documentation. pucch_processor_result process(const resource_grid_reader& grid, const format4_configuration& config) override { // TBD. - return pucch_processor_result(); + return {}; } /// PUCCH processor constructor. @@ -102,8 +102,6 @@ class pucch_processor_impl : public pucch_processor } private: - /// Validates PUCCH Format 1 configuration. - void assert_format1_config(const pucch_processor::format1_configuration& config); /// Validates PUCCH Format 2 configuration. void assert_format2_config(const pucch_processor::format2_configuration& config); diff --git a/lib/phy/upper/upper_phy_pdu_validators.h b/lib/phy/upper/upper_phy_pdu_validators.h index 8542a5ccc2..ead35b588d 100644 --- a/lib/phy/upper/upper_phy_pdu_validators.h +++ b/lib/phy/upper/upper_phy_pdu_validators.h @@ -39,7 +39,10 @@ class uplink_processor_validator_impl : public uplink_pdu_validator { return pucch->is_valid(config).has_value(); } - bool is_valid(const pucch_processor::format1_configuration& config) const override { return pucch->is_valid(config); } + bool is_valid(const pucch_processor::format1_configuration& config) const override + { + return pucch->is_valid(config).has_value(); + } bool is_valid(const pucch_processor::format2_configuration& config) const override { return pucch->is_valid(config); } bool is_valid(const pucch_processor::format3_configuration& config) const override { return pucch->is_valid(config); } bool is_valid(const pucch_processor::format4_configuration& config) const override { return pucch->is_valid(config); } diff --git a/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format1_test.cpp b/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format1_test.cpp index 69b67561c1..12880dcfe8 100644 --- a/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format1_test.cpp +++ b/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format1_test.cpp @@ -15,19 +15,20 @@ #include "srsran/ran/pucch/pucch_constants.h" #include "fmt/ostream.h" #include "gtest/gtest.h" +#include using namespace srsran; namespace { // Maximum channel dimensions used to construct the PUCCH processor. -static channel_estimate::channel_estimate_dimensions max_dimensions = {MAX_RB, - MAX_NSYMB_PER_SLOT - 1, - 1, - pucch_constants::MAX_LAYERS}; +channel_estimate::channel_estimate_dimensions max_dimensions = {MAX_RB, + MAX_NSYMB_PER_SLOT - 1, + 1, + pucch_constants::MAX_LAYERS}; /// Minimum number of symbols (including DM-RS) that NR-PUCCH Format 1 can transmit. -static constexpr unsigned PUCCH_FORMAT1_MIN_NSYMB = 4; +constexpr unsigned PUCCH_FORMAT1_MIN_NSYMB = 4; // Valid PUCCH Format 1 configuration. const pucch_processor::format1_configuration base_format_1_config = { @@ -270,7 +271,10 @@ TEST_P(PucchProcessorFormat1Fixture, PucchProcessorValidatortest) const test_case_t& param = GetParam(); // Make sure the configuration is invalid. - ASSERT_FALSE(pucch_validator->is_valid(param.get_test_params().config)); + error_type validator_out = pucch_validator->is_valid(param.get_test_params().config); + ASSERT_FALSE(validator_out.has_value()) << "Validation should fail."; + ASSERT_TRUE(std::regex_match(validator_out.error(), std::regex(param.get_test_params().assert_message))) + << "The assertion message doesn't match the expected pattern."; // Prepare resource grid. resource_grid_reader_spy grid; From 333185aca15485e6ae83c921938fd81d1608e74a Mon Sep 17 00:00:00 2001 From: dvdgrgrtt Date: Fri, 6 Sep 2024 10:32:57 +0200 Subject: [PATCH 010/174] phy: refactor pucch format 2 validator Return an error_type instead of a simple bool. --- .../channel_processors/pucch_processor.h | 5 +- .../pucch_processor_impl.cpp | 127 +++++++----------- .../channel_processors/pucch_processor_impl.h | 5 +- lib/phy/upper/upper_phy_pdu_validators.h | 5 +- ...pucch_processor_validator_format2_test.cpp | 12 +- 5 files changed, 65 insertions(+), 89 deletions(-) diff --git a/include/srsran/phy/upper/channel_processors/pucch_processor.h b/include/srsran/phy/upper/channel_processors/pucch_processor.h index 239d9f4acc..47558de5d4 100644 --- a/include/srsran/phy/upper/channel_processors/pucch_processor.h +++ b/include/srsran/phy/upper/channel_processors/pucch_processor.h @@ -17,6 +17,7 @@ #include "srsran/ran/cyclic_prefix.h" #include "srsran/ran/pucch/pucch_context.h" #include "srsran/ran/slot_point.h" +#include namespace srsran { @@ -238,8 +239,8 @@ class pucch_pdu_validator virtual error_type is_valid(const pucch_processor::format1_configuration& config) const = 0; /// \brief Validates PUCCH Format 2 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format2_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format2_configuration& config) const = 0; /// \brief Validates PUCCH Format 3 configuration parameters. /// \return True if the parameters contained in \c config are supported, false otherwise. diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp index 742172bb7c..9e781115b4 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp @@ -137,7 +137,8 @@ pucch_processor_result pucch_processor_impl::process(const resource_grid_reader& const format2_configuration& config) { // Check that the PUCCH Format 2 configuration is valid. - assert_format2_config(config); + [[maybe_unused]] std::string msg; + srsran_assert(handle_validation(msg, pdu_validator->is_valid(config)), "{}", msg); pucch_processor_result result; @@ -221,65 +222,6 @@ pucch_processor_result pucch_processor_impl::process(const resource_grid_reader& return result; } -void pucch_processor_impl::assert_format2_config(const pucch_processor::format2_configuration& config) -{ - // Assert BWP allocation. - srsran_assert(config.bwp_start_rb + config.bwp_size_rb <= max_sizes.nof_prb, - "BWP allocation goes up to PRB {}, exceeding the configured maximum grid RB size, i.e., {}.", - config.bwp_start_rb + config.bwp_size_rb, - max_sizes.nof_prb); - - // Assert that the PRB set is constrained to the BWP. - srsran_assert(config.starting_prb + config.nof_prb <= config.bwp_size_rb, - "PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", - config.starting_prb + config.nof_prb, - config.bwp_size_rb); - - // Assert that the OFDM symbols are constrained to the slot dimensions given by the CP. - srsran_assert(config.start_symbol_index + config.nof_symbols <= get_nsymb_per_slot(config.cp), - "OFDM symbol allocation goes up to symbol {}, exceeding the number of symbols in the given slot with " - "{} CP, i.e., {}.", - config.start_symbol_index + config.nof_symbols, - config.cp.to_string(), - get_nsymb_per_slot(config.cp)); - - // Assert that the OFDM symbols are within the configured maximum slot dimensions. - srsran_assert( - config.start_symbol_index + config.nof_symbols <= max_sizes.nof_symbols, - "OFDM symbol allocation goes up to symbol {}, exceeding the configured maximum number of slot symbols, i.e., {}.", - config.start_symbol_index + config.nof_symbols, - max_sizes.nof_symbols); - - // Assert the number of receive ports. - srsran_assert(!config.ports.empty(), "The number of receive ports cannot be zero."); - - srsran_assert( - config.ports.size() <= max_sizes.nof_rx_ports, - "The number of receive ports, i.e. {}, exceeds the configured maximum number of receive ports, i.e., {}.", - config.ports.size(), - max_sizes.nof_rx_ports); - - // CSI is not currently supported. - srsran_assert(config.nof_csi_part2 == 0, "CSI Part 2 is not currently supported."); - - // Expected UCI payload length. - unsigned uci_payload_len = config.nof_harq_ack + config.nof_sr + config.nof_csi_part1 + config.nof_csi_part2; - - // Calculate effective code rate. - float effective_code_rate = pucch_format2_code_rate(config.nof_prb, config.nof_symbols, uci_payload_len); - srsran_assert(effective_code_rate <= pucch_constants::MAX_CODE_RATE, - "The effective code rate (i.e., {}) exceeds the maximum allowed {}.", - effective_code_rate, - static_cast(pucch_constants::MAX_CODE_RATE)); - - srsran_assert((uci_payload_len >= pucch_constants::FORMAT2_MIN_UCI_NBITS) && - (uci_payload_len <= FORMAT2_MAX_UCI_NBITS), - "UCI Payload length, i.e., {} is not supported. Payload length must be {} to {} bits.", - uci_payload_len, - pucch_constants::FORMAT2_MIN_UCI_NBITS, - static_cast(FORMAT2_MAX_UCI_NBITS)); -} - error_type pucch_pdu_validator_impl::is_valid(const pucch_processor::format0_configuration& config) const { // BWP PRB shall not exceed the maximum. @@ -415,50 +357,79 @@ error_type pucch_pdu_validator_impl::is_valid(const pucch_processor return default_success_t(); } -bool pucch_pdu_validator_impl::is_valid(const pucch_processor::format2_configuration& config) const +error_type pucch_pdu_validator_impl::is_valid(const pucch_processor::format2_configuration& config) const { - // Count total number of payload bits. - unsigned nof_uci_bits = config.nof_harq_ack + config.nof_sr + config.nof_csi_part1 + config.nof_csi_part2; - - // Calculate effective code rate. - float effective_code_rate = pucch_format2_code_rate(config.nof_prb, config.nof_symbols, nof_uci_bits); - // The BWP size exceeds the grid dimensions. if ((config.bwp_start_rb + config.bwp_size_rb) > ce_dims.nof_prb) { - return false; + return make_unexpected( + fmt::format("BWP allocation goes up to PRB {}, exceeding the configured maximum grid RB size, i.e., {}.", + config.bwp_start_rb + config.bwp_size_rb, + ce_dims.nof_prb)); } // None of the occupied PRB within the BWP can exceed the BWP dimensions. if (config.starting_prb + config.nof_prb > config.bwp_size_rb) { - return false; + return make_unexpected(fmt::format("PRB allocation within the BWP goes up to PRB {}, exceeding BWP size, i.e., {}.", + config.starting_prb + config.nof_prb, + config.bwp_size_rb)); } // None of the occupied symbols can exceed the configured maximum slot size, or the slot size given by the CP. - if ((config.start_symbol_index + config.nof_symbols > get_nsymb_per_slot(config.cp)) || - (config.start_symbol_index + config.nof_symbols > ce_dims.nof_symbols)) { - return false; + if (config.start_symbol_index + config.nof_symbols > get_nsymb_per_slot(config.cp)) { + return make_unexpected(fmt::format( + "OFDM symbol allocation goes up to symbol {}, exceeding the number of symbols in the given slot with " + "{} CP, i.e., {}.", + config.start_symbol_index + config.nof_symbols, + config.cp.to_string(), + get_nsymb_per_slot(config.cp))); + } + + if (config.start_symbol_index + config.nof_symbols > ce_dims.nof_symbols) { + return make_unexpected(fmt::format("OFDM symbol allocation goes up to symbol {}, exceeding the configured maximum " + "number of slot symbols, i.e., {}.", + config.start_symbol_index + config.nof_symbols, + ce_dims.nof_symbols)); } // The number of receive ports is either zero or exceeds the configured maximum number of receive ports. - if (config.ports.empty() || (config.ports.size() > ce_dims.nof_rx_ports)) { - return false; + if (config.ports.empty()) { + return make_unexpected(fmt::format("The number of receive ports cannot be zero.")); + } + + if (config.ports.size() > ce_dims.nof_rx_ports) { + return make_unexpected(fmt::format( + "The number of receive ports, i.e. {}, exceeds the configured maximum number of receive ports, i.e., {}.", + config.ports.size(), + ce_dims.nof_rx_ports)); } // CSI Part 2 is not supported. if (config.nof_csi_part2 != 0) { - return false; + return make_unexpected(fmt::format("CSI Part 2 is not currently supported.")); } + // Count total number of payload bits. + unsigned nof_uci_bits = config.nof_harq_ack + config.nof_sr + config.nof_csi_part1 + config.nof_csi_part2; + + // Calculate effective code rate. + float effective_code_rate = pucch_format2_code_rate(config.nof_prb, config.nof_symbols, nof_uci_bits); + // The code rate shall not exceed the maximum. if (effective_code_rate > pucch_constants::MAX_CODE_RATE) { - return false; + return make_unexpected(fmt::format("The effective code rate (i.e., {}) exceeds the maximum allowed {}.", + effective_code_rate, + static_cast(pucch_constants::MAX_CODE_RATE))); } // UCI payload exceeds the UCI payload size boundaries. if (nof_uci_bits < pucch_constants::FORMAT2_MIN_UCI_NBITS || nof_uci_bits > pucch_processor_impl::FORMAT2_MAX_UCI_NBITS) { - return false; + return make_unexpected( + fmt::format("UCI Payload length, i.e., {} is not supported. Payload length must be {} to {} bits.", + nof_uci_bits, + pucch_constants::FORMAT2_MIN_UCI_NBITS, + static_cast(pucch_processor_impl::FORMAT2_MAX_UCI_NBITS))); } - return true; + return default_success_t(); } diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.h b/lib/phy/upper/channel_processors/pucch_processor_impl.h index 3db06aaaf5..6908ed5b97 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.h +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.h @@ -38,7 +38,7 @@ class pucch_pdu_validator_impl : public pucch_pdu_validator // See interface for documentation. error_type is_valid(const pucch_processor::format0_configuration& config) const override; error_type is_valid(const pucch_processor::format1_configuration& config) const override; - bool is_valid(const pucch_processor::format2_configuration& config) const override; + error_type is_valid(const pucch_processor::format2_configuration& config) const override; bool is_valid(const pucch_processor::format3_configuration& config) const override { return true; } bool is_valid(const pucch_processor::format4_configuration& config) const override { return true; } @@ -102,9 +102,6 @@ class pucch_processor_impl : public pucch_processor } private: - /// Validates PUCCH Format 2 configuration. - void assert_format2_config(const pucch_processor::format2_configuration& config); - /// PUCCH PDU validator for all formats. std::unique_ptr pdu_validator; /// Channel estimator for PUCCH Format 1. diff --git a/lib/phy/upper/upper_phy_pdu_validators.h b/lib/phy/upper/upper_phy_pdu_validators.h index ead35b588d..bdc772868f 100644 --- a/lib/phy/upper/upper_phy_pdu_validators.h +++ b/lib/phy/upper/upper_phy_pdu_validators.h @@ -43,7 +43,10 @@ class uplink_processor_validator_impl : public uplink_pdu_validator { return pucch->is_valid(config).has_value(); } - bool is_valid(const pucch_processor::format2_configuration& config) const override { return pucch->is_valid(config); } + bool is_valid(const pucch_processor::format2_configuration& config) const override + { + return pucch->is_valid(config).has_value(); + } bool is_valid(const pucch_processor::format3_configuration& config) const override { return pucch->is_valid(config); } bool is_valid(const pucch_processor::format4_configuration& config) const override { return pucch->is_valid(config); } bool is_valid(const pusch_processor::pdu_t& config) const override { return pusch->is_valid(config); } diff --git a/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format2_test.cpp b/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format2_test.cpp index 44a5a03c35..27b3f58d3b 100644 --- a/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format2_test.cpp +++ b/tests/unittests/phy/upper/channel_processors/pucch_processor_validator_format2_test.cpp @@ -15,6 +15,7 @@ #include "srsran/ran/pucch/pucch_constants.h" #include "fmt/ostream.h" #include "gtest/gtest.h" +#include using namespace srsran; @@ -144,7 +145,7 @@ const std::vector pucch_processor_validator_test_data = { test_params entry = {}; entry.config = base_format_2_config; entry.config.ports = {}; - entry.assert_message = fmt::format(R"(The number of receive ports cannot be zero\.)"); + entry.assert_message = R"(The number of receive ports cannot be zero\.)"; return entry; }, }, @@ -165,7 +166,7 @@ const std::vector pucch_processor_validator_test_data = { test_params entry = {}; entry.config = base_format_2_config; entry.config.nof_csi_part2 = 1; - entry.assert_message = fmt::format(R"(CSI Part 2 is not currently supported\.)"); + entry.assert_message = R"(CSI Part 2 is not currently supported\.)"; return entry; }, }, @@ -191,7 +192,7 @@ const std::vector pucch_processor_validator_test_data = { entry.config = base_format_2_config; entry.config.nof_harq_ack = uci_constants::MAX_NOF_HARQ_BITS; entry.assert_message = - R"(The effective code rate \(i\.e\., [0-9]*\.[0-9]*) exceeds the maximum allowed 0\.8\.)"; + R"(The effective code rate \(i\.e\., [0-9]*\.[0-9]*\) exceeds the maximum allowed 0\.8\.)"; return entry; }, }, @@ -317,7 +318,10 @@ TEST_P(PucchProcessorFormat2Fixture, PucchProcessorValidatortest) const test_case_t& param = GetParam(); // Make sure the configuration is invalid. - ASSERT_FALSE(pucch_validator->is_valid(param.get_test_params().config)); + error_type validator_out = pucch_validator->is_valid(param.get_test_params().config); + ASSERT_FALSE(validator_out.has_value()) << "Validation should fail."; + ASSERT_TRUE(std::regex_match(validator_out.error(), std::regex(param.get_test_params().assert_message))) + << "The assertion message doesn't match the expected pattern."; // Prepare resource grid. resource_grid_reader_spy grid; From 37586c1c812141d5e97e850eef6bbf7282618ece Mon Sep 17 00:00:00 2001 From: dvdgrgrtt Date: Fri, 6 Sep 2024 10:41:22 +0200 Subject: [PATCH 011/174] phy: refactor pucch formats 3 and 4 validators Return an error_type instead of a simple bool. Just updating the signatures for future use, since PUCCH Formats 3 and 4 are not supported yet. --- .../phy/upper/channel_processors/pucch_processor.h | 8 ++++---- .../upper/channel_processors/pucch_processor_impl.h | 10 ++++++++-- lib/phy/upper/upper_phy_pdu_validators.h | 10 ++++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/include/srsran/phy/upper/channel_processors/pucch_processor.h b/include/srsran/phy/upper/channel_processors/pucch_processor.h index 47558de5d4..08f54ed787 100644 --- a/include/srsran/phy/upper/channel_processors/pucch_processor.h +++ b/include/srsran/phy/upper/channel_processors/pucch_processor.h @@ -243,12 +243,12 @@ class pucch_pdu_validator virtual error_type is_valid(const pucch_processor::format2_configuration& config) const = 0; /// \brief Validates PUCCH Format 3 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format3_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format3_configuration& config) const = 0; /// \brief Validates PUCCH Format 4 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format4_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format4_configuration& config) const = 0; }; } // namespace srsran diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.h b/lib/phy/upper/channel_processors/pucch_processor_impl.h index 6908ed5b97..efe56ec168 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.h +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.h @@ -39,8 +39,14 @@ class pucch_pdu_validator_impl : public pucch_pdu_validator error_type is_valid(const pucch_processor::format0_configuration& config) const override; error_type is_valid(const pucch_processor::format1_configuration& config) const override; error_type is_valid(const pucch_processor::format2_configuration& config) const override; - bool is_valid(const pucch_processor::format3_configuration& config) const override { return true; } - bool is_valid(const pucch_processor::format4_configuration& config) const override { return true; } + error_type is_valid(const pucch_processor::format3_configuration& config) const override + { + return default_success_t(); + } + error_type is_valid(const pucch_processor::format4_configuration& config) const override + { + return default_success_t(); + } private: /// Maximum transmit and receive resource grid dimensions handled by the PUCCH processor. diff --git a/lib/phy/upper/upper_phy_pdu_validators.h b/lib/phy/upper/upper_phy_pdu_validators.h index bdc772868f..b303d3b2a2 100644 --- a/lib/phy/upper/upper_phy_pdu_validators.h +++ b/lib/phy/upper/upper_phy_pdu_validators.h @@ -47,8 +47,14 @@ class uplink_processor_validator_impl : public uplink_pdu_validator { return pucch->is_valid(config).has_value(); } - bool is_valid(const pucch_processor::format3_configuration& config) const override { return pucch->is_valid(config); } - bool is_valid(const pucch_processor::format4_configuration& config) const override { return pucch->is_valid(config); } + bool is_valid(const pucch_processor::format3_configuration& config) const override + { + return pucch->is_valid(config).has_value(); + } + bool is_valid(const pucch_processor::format4_configuration& config) const override + { + return pucch->is_valid(config).has_value(); + } bool is_valid(const pusch_processor::pdu_t& config) const override { return pusch->is_valid(config); } bool is_valid(const srs_estimator_configuration& config) const override { return srs->is_valid(config); } From 41eddac188b1168ff9a0b2c880fefe47483c62f2 Mon Sep 17 00:00:00 2001 From: dvdgrgrtt Date: Mon, 9 Sep 2024 11:30:21 +0200 Subject: [PATCH 012/174] pucch: propagate phy validator error msg to fapi --- include/srsran/phy/upper/uplink_processor.h | 20 +++++++------- .../phy/fapi_to_phy_translator.cpp | 12 ++++++--- lib/phy/upper/upper_phy_pdu_validators.h | 20 +++++++------- .../phy/fapi_to_phy_translator_test.cpp | 27 ++++++++++++++----- 4 files changed, 49 insertions(+), 30 deletions(-) diff --git a/include/srsran/phy/upper/uplink_processor.h b/include/srsran/phy/upper/uplink_processor.h index a4142adfcf..e064ca0e92 100644 --- a/include/srsran/phy/upper/uplink_processor.h +++ b/include/srsran/phy/upper/uplink_processor.h @@ -141,24 +141,24 @@ class uplink_pdu_validator virtual bool is_valid(const prach_detector::configuration& config) const = 0; /// \brief Validates PUCCH Format 0 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format0_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format0_configuration& config) const = 0; /// \brief Validates PUCCH Format 1 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format1_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format1_configuration& config) const = 0; /// \brief Validates PUCCH Format 2 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format2_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format2_configuration& config) const = 0; /// \brief Validates PUCCH Format 3 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format3_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format3_configuration& config) const = 0; /// \brief Validates PUCCH Format 4 configuration parameters. - /// \return True if the parameters contained in \c config are supported, false otherwise. - virtual bool is_valid(const pucch_processor::format4_configuration& config) const = 0; + /// \return A success if the parameters contained in \c config are supported, an error message otherwise. + virtual error_type is_valid(const pucch_processor::format4_configuration& config) const = 0; /// \brief Validates PUSCH configuration parameters. /// \return True if the parameters contained in \c config are supported, false otherwise. diff --git a/lib/fapi_adaptor/phy/fapi_to_phy_translator.cpp b/lib/fapi_adaptor/phy/fapi_to_phy_translator.cpp index d279f65a5b..6191696e42 100644 --- a/lib/fapi_adaptor/phy/fapi_to_phy_translator.cpp +++ b/lib/fapi_adaptor/phy/fapi_to_phy_translator.cpp @@ -354,7 +354,8 @@ void fapi_to_phy_translator::dl_tti_request(const fapi::dl_tti_request_message& } /// Returns true if the given PUCCH PDU is valid, otherwise false. -static bool is_pucch_pdu_valid(const uplink_pdu_validator& ul_pdu_validator, const uplink_processor::pucch_pdu& ul_pdu) +static error_type is_pucch_pdu_valid(const uplink_pdu_validator& ul_pdu_validator, + const uplink_processor::pucch_pdu& ul_pdu) { switch (ul_pdu.context.format) { case pucch_format::FORMAT_0: @@ -371,7 +372,7 @@ static bool is_pucch_pdu_valid(const uplink_pdu_validator& ul_pdu_validator, con break; } - return false; + return make_unexpected("Unknown PUCCH format."); } /// Returns a PRACH detector slot configuration using the given PRACH buffer context. @@ -424,8 +425,11 @@ static expected translate_ul_tti_pdus_to_phy_pdus(const fapi::ul_tt case fapi::ul_pdu_type::PUCCH: { uplink_processor::pucch_pdu& ul_pdu = pdus.pucch.emplace_back(); convert_pucch_fapi_to_phy(ul_pdu, pdu.pucch_pdu, msg.sfn, msg.slot, carrier_cfg.num_rx_ant); - if (!is_pucch_pdu_valid(ul_pdu_validator, ul_pdu)) { - logger.warning("Upper PHY flagged a PUCCH PDU as having an invalid configuration. Skipping UL_TTI.request"); + error_type phy_pucch_validation = is_pucch_pdu_valid(ul_pdu_validator, ul_pdu); + if (!phy_pucch_validation.has_value()) { + logger.warning( + "Skipping UL_TTI.request: PUCCH PDU flagged as invalid by the Upper PHY with the following error\n {}", + phy_pucch_validation.error()); return make_unexpected(default_error_t{}); } diff --git a/lib/phy/upper/upper_phy_pdu_validators.h b/lib/phy/upper/upper_phy_pdu_validators.h index b303d3b2a2..8fc3b97207 100644 --- a/lib/phy/upper/upper_phy_pdu_validators.h +++ b/lib/phy/upper/upper_phy_pdu_validators.h @@ -35,25 +35,25 @@ class uplink_processor_validator_impl : public uplink_pdu_validator // See interface for documentation. bool is_valid(const prach_detector::configuration& config) const override { return prach->is_valid(config); } - bool is_valid(const pucch_processor::format0_configuration& config) const override + error_type is_valid(const pucch_processor::format0_configuration& config) const override { - return pucch->is_valid(config).has_value(); + return pucch->is_valid(config); } - bool is_valid(const pucch_processor::format1_configuration& config) const override + error_type is_valid(const pucch_processor::format1_configuration& config) const override { - return pucch->is_valid(config).has_value(); + return pucch->is_valid(config); } - bool is_valid(const pucch_processor::format2_configuration& config) const override + error_type is_valid(const pucch_processor::format2_configuration& config) const override { - return pucch->is_valid(config).has_value(); + return pucch->is_valid(config); } - bool is_valid(const pucch_processor::format3_configuration& config) const override + error_type is_valid(const pucch_processor::format3_configuration& config) const override { - return pucch->is_valid(config).has_value(); + return pucch->is_valid(config); } - bool is_valid(const pucch_processor::format4_configuration& config) const override + error_type is_valid(const pucch_processor::format4_configuration& config) const override { - return pucch->is_valid(config).has_value(); + return pucch->is_valid(config); } bool is_valid(const pusch_processor::pdu_t& config) const override { return pusch->is_valid(config); } bool is_valid(const srs_estimator_configuration& config) const override { return srs->is_valid(config); } diff --git a/tests/unittests/fapi_adaptor/phy/fapi_to_phy_translator_test.cpp b/tests/unittests/fapi_adaptor/phy/fapi_to_phy_translator_test.cpp index 524c7693d9..ad4abb7b62 100644 --- a/tests/unittests/fapi_adaptor/phy/fapi_to_phy_translator_test.cpp +++ b/tests/unittests/fapi_adaptor/phy/fapi_to_phy_translator_test.cpp @@ -58,12 +58,27 @@ class downlink_pdu_validator_dummy : public downlink_pdu_validator class uplink_pdu_validator_dummy : public uplink_pdu_validator { public: - bool is_valid(const prach_detector::configuration& config) const override { return true; } - bool is_valid(const pucch_processor::format0_configuration& config) const override { return true; } - bool is_valid(const pucch_processor::format1_configuration& config) const override { return true; } - bool is_valid(const pucch_processor::format2_configuration& config) const override { return true; } - bool is_valid(const pucch_processor::format3_configuration& config) const override { return true; } - bool is_valid(const pucch_processor::format4_configuration& config) const override { return true; } + bool is_valid(const prach_detector::configuration& config) const override { return true; } + error_type is_valid(const pucch_processor::format0_configuration& config) const override + { + return default_success_t(); + } + error_type is_valid(const pucch_processor::format1_configuration& config) const override + { + return default_success_t(); + } + error_type is_valid(const pucch_processor::format2_configuration& config) const override + { + return default_success_t(); + } + error_type is_valid(const pucch_processor::format3_configuration& config) const override + { + return default_success_t(); + } + error_type is_valid(const pucch_processor::format4_configuration& config) const override + { + return default_success_t(); + } bool is_valid(const pusch_processor::pdu_t& pdu) const override { return true; } bool is_valid(const srs_estimator_configuration& config) const override { return true; } }; From f390d31fef74575619d2101a78698bc8ad8d59e3 Mon Sep 17 00:00:00 2001 From: qarlosalberto Date: Tue, 10 Sep 2024 12:49:42 +0200 Subject: [PATCH 013/174] ci: increase max_puschs_per_slot --- tests/e2e/tests/viavi/test_declaration.yml | 20 +++++++++---------- .../tests/viavi/test_declaration_debug.yml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index fe12b9e05c..9caeb9e201 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -48,7 +48,7 @@ tests: gnb_extra_commands: *gnb_extra_commands id: "32UE ideal UDP bidirectional" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_high @@ -104,7 +104,7 @@ tests: gnb_extra_commands: *gnb_extra_commands id: "32UE ideal TCP downlink" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_low @@ -132,7 +132,7 @@ tests: gnb_extra_commands: *gnb_extra_commands id: "32UE fading TCP bidirectional" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: 1 @@ -146,7 +146,7 @@ tests: gnb_extra_commands: "log --ngap_level=debug --rrc_level=debug" id: "32UE ideal UDP attach-detach with traffic" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_low @@ -160,7 +160,7 @@ tests: # gnb_extra_commands: *gnb_extra_commands # id: "32UE fading UDP attach-detach with traffic" # max_pdschs_per_slot: 1 - # max_puschs_per_slot: 1 + # max_puschs_per_slot: 4 # enable_qos_viavi: false # # test/fail criteria # expected_dl_bitrate: *expected_dl_bitrate_low @@ -188,7 +188,7 @@ tests: # gnb_extra_commands: *gnb_extra_commands # id: "32UE birth-death UDP bidirectional" # max_pdschs_per_slot: 1 - # max_puschs_per_slot: 1 + # max_puschs_per_slot: 4 # enable_qos_viavi: false # # test/fail criteria # expected_dl_bitrate: *expected_dl_bitrate_low @@ -202,7 +202,7 @@ tests: gnb_extra_commands: "log --all_level=info" id: "32UE ideal ping" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_low @@ -216,7 +216,7 @@ tests: gnb_extra_commands: *gnb_extra_commands id: "32UE ideal ping with traffic" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_low @@ -230,7 +230,7 @@ tests: gnb_extra_commands: *gnb_extra_commands id: "experimental 32UE ideal UDP bidirectional Long" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_high @@ -244,7 +244,7 @@ tests: gnb_extra_commands: *gnb_extra_commands id: "experimental 32UE ideal UDP bidirectional Long extended" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_high diff --git a/tests/e2e/tests/viavi/test_declaration_debug.yml b/tests/e2e/tests/viavi/test_declaration_debug.yml index 614ae29bc6..73630164b3 100644 --- a/tests/e2e/tests/viavi/test_declaration_debug.yml +++ b/tests/e2e/tests/viavi/test_declaration_debug.yml @@ -31,7 +31,7 @@ tests: gnb_extra_commands: *gnb_extra_commands id: "32UE ideal UDP bidirectional - Debug" max_pdschs_per_slot: 1 - max_puschs_per_slot: 1 + max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria expected_dl_bitrate: *expected_dl_bitrate_high From 8ea84c3d7640544a11999d33c0b5f2d0bd1a285d Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 10 Sep 2024 17:45:22 +0200 Subject: [PATCH 014/174] Introduce srs_du namespace in for all the DU classes --- apps/du/du.cpp | 2 +- apps/gnb/gnb.cpp | 2 +- apps/services/worker_manager.cpp | 22 ++++----- apps/services/worker_manager.h | 4 +- .../du_high/du_high_config_translators.cpp | 36 +++++++-------- .../du_high/du_high_config_translators.h | 8 ++-- .../du_high/du_high_wrapper_config_helper.cpp | 26 +++++------ .../du_high/du_high_wrapper_config_helper.h | 34 +++++++------- .../du_low/du_low_config_translator.cpp | 30 ++++++------- .../du_low/du_low_config_translator.h | 17 ++++--- .../du_low/du_low_wrapper_config_helper.cpp | 22 ++++----- .../du_low/du_low_wrapper_config_helper.h | 25 ++++++----- apps/units/flexible_du/du_unit.h | 2 +- .../split_7_2/ru_ofh_config_translator.cpp | 18 ++++---- .../split_7_2/ru_ofh_config_translator.h | 9 ++-- .../flexible_du/split_7_2/ru_ofh_factories.h | 8 ++-- .../split_8/ru_sdr_config_translator.cpp | 22 ++++----- .../split_8/ru_sdr_config_translator.h | 8 ++-- .../flexible_du/split_8/ru_sdr_factories.h | 9 ++-- .../split_dynamic/dynamic_du_factory.cpp | 18 ++++---- .../split_dynamic/dynamic_du_impl.cpp | 2 +- .../split_dynamic/dynamic_du_impl.h | 18 ++++---- .../split_dynamic/dynamic_du_translators.cpp | 10 ++--- .../split_dynamic/dynamic_du_translators.h | 11 +++-- include/srsran/adt/bounded_bitset.h | 2 +- include/srsran/adt/byte_buffer.h | 2 +- include/srsran/adt/detail/type_storage.h | 4 +- include/srsran/adt/ring_buffer.h | 2 +- include/srsran/adt/slotted_array.h | 2 +- include/srsran/asn1/asn1_utils.h | 2 +- include/srsran/du/du.h | 3 ++ include/srsran/du/du_cell_config.h | 2 + include/srsran/du/du_cell_config_helpers.h | 4 +- include/srsran/du/du_cell_config_validation.h | 2 + include/srsran/du/du_high/du_high.h | 2 + .../srsran/du/du_high/du_high_configuration.h | 28 ++++++------ .../du/du_high/du_high_executor_mapper.h | 2 + include/srsran/du/du_high/du_high_factory.h | 2 + include/srsran/du/du_high/du_high_wrapper.h | 5 ++- .../du/du_high/du_high_wrapper_config.h | 5 ++- .../du/du_high/du_high_wrapper_factory.h | 2 + .../du/du_high/du_manager/du_configurator.h | 2 + .../du/du_high/du_manager/du_manager_params.h | 5 +++ include/srsran/du/du_high/du_qos_config.h | 2 + .../srsran/du/du_high/du_qos_config_helpers.h | 19 ++++---- include/srsran/du/du_high/du_srb_config.h | 2 + include/srsran/du/du_low/du_low.h | 3 ++ include/srsran/du/du_low/du_low_config.h | 4 +- include/srsran/du/du_low/du_low_factory.h | 2 + include/srsran/du/du_low/du_low_wrapper.h | 3 ++ .../srsran/du/du_low/du_low_wrapper_config.h | 2 + .../srsran/du/du_low/du_low_wrapper_factory.h | 3 +- include/srsran/du/du_update_config_helpers.h | 13 +++--- include/srsran/du/du_wrapper.h | 2 + include/srsran/du/du_wrapper_config.h | 2 + include/srsran/du/du_wrapper_factory.h | 2 + include/srsran/e1ap/common/e1ap_types.h | 4 +- include/srsran/e2/e2_event_manager.h | 4 +- include/srsran/e2/e2_factory.h | 2 +- include/srsran/f1ap/common/f1ap_ue_id.h | 4 +- include/srsran/f1ap/du/f1c_bearer.h | 14 ++++++ .../config/mac_cell_group_config_factory.h | 2 +- .../srsran/mac/config/mac_config_helpers.h | 4 +- include/srsran/mac/mac_config.h | 14 +++--- include/srsran/ngap/ngap_types.h | 4 +- include/srsran/nru/nru_packing.h | 2 +- .../ofh/ethernet/ethernet_unique_buffer.h | 2 +- include/srsran/pdcp/pdcp_config.h | 4 +- include/srsran/psup/psup_message.h | 2 +- include/srsran/ran/csi_rs/csi_meas_config.h | 2 +- include/srsran/ran/cu_types.h | 4 +- include/srsran/ran/duplex_mode.h | 2 +- include/srsran/ran/frequency_range.h | 2 +- include/srsran/ran/lcid.h | 4 +- include/srsran/ran/pci.h | 9 +++- include/srsran/ran/pci_helpers.h | 31 ------------- include/srsran/ran/pdcch/pdcch_candidates.h | 2 +- include/srsran/ran/qos/five_qi.h | 2 +- include/srsran/ran/qos/qos_flow_id.h | 4 +- include/srsran/ran/qos/qos_prio_level.h | 2 +- include/srsran/rlc/rlc_config.h | 4 +- include/srsran/rlc/rlc_mode.h | 4 +- include/srsran/rlc/rlc_tx_metrics.h | 2 +- .../config/sched_cell_config_helpers.h | 3 +- include/srsran/scheduler/scheduler_metrics.h | 4 +- include/srsran/sdap/sdap_config.h | 4 +- include/srsran/security/security.h | 8 ++-- include/srsran/security/ssl.h | 2 +- include/srsran/security/zuc.h | 2 +- lib/asn1/asn1_utils.cpp | 2 +- lib/du/du_cell_config_validation.cpp | 3 +- .../adapters/du_high_adapter_factories.h | 2 + .../adapters/mac_test_mode_adapter.cpp | 5 ++- .../du_high/adapters/mac_test_mode_adapter.h | 2 + lib/du/du_high/du_high_executor_strategies.h | 2 + lib/du/du_high/du_high_factory.cpp | 3 +- lib/du/du_high/du_high_wrapper_factory.cpp | 6 ++- lib/du/du_high/du_high_wrapper_impl.cpp | 1 + lib/du/du_high/du_high_wrapper_impl.h | 2 + .../converters/asn1_rrc_config_helpers.cpp | 4 +- .../converters/f1ap_configuration_helpers.cpp | 1 + .../converters/f1ap_configuration_helpers.h | 2 - .../scheduler_configuration_helpers.cpp | 6 +-- .../scheduler_configuration_helpers.h | 12 +++-- lib/du/du_high/du_manager/du_manager_impl.h | 2 +- lib/du/du_high/du_manager/du_ue/du_bearer.cpp | 14 +++--- .../du_ue/du_ue_controller_impl.cpp | 6 +-- .../du_manager/procedures/procedure_logger.h | 4 +- .../procedures/ue_configuration_procedure.cpp | 2 +- .../procedures/ue_creation_procedure.cpp | 2 +- .../du_pucch_resource_manager.cpp | 6 +-- lib/du/du_low/du_low_factory.cpp | 5 ++- lib/du/du_low/du_low_impl.cpp | 4 +- lib/du/du_low/du_low_impl.h | 2 + lib/du/du_low/du_low_wrapper_factory.cpp | 5 ++- lib/du/du_low/du_low_wrapper_impl.cpp | 1 + lib/du/du_low/du_low_wrapper_impl.h | 2 + lib/du/du_update_config_helpers.cpp | 17 +++---- lib/du/du_wrapper_factory.cpp | 3 +- lib/du/du_wrapper_impl.cpp | 1 + lib/du/du_wrapper_impl.h | 2 + .../procedures/e1ap_transaction_manager.h | 4 +- .../procedures/e1ap_cu_up_event_manager.h | 2 +- lib/e2/common/e2_entity.cpp | 2 +- lib/e2/common/e2_entity.h | 2 +- lib/e2/common/e2_factory.cpp | 2 +- .../e2sm_rc_control_action_du_executor.cpp | 45 ++++++++++--------- .../e2sm_rc_control_action_du_executor.h | 18 ++++---- .../du/procedures/f1ap_du_event_manager.h | 2 +- .../buffered_slot_gateway_impl.cpp | 2 +- .../sctp_network_gateway_common_impl.h | 2 +- .../config/mac_cell_group_config_factory.cpp | 3 +- lib/mac/config/mac_config_helpers.cpp | 6 +-- lib/mac/mac_ctrl/mac_config.h | 18 ++++---- lib/mac/mac_dl/mac_dl_processor.h | 10 ++--- lib/mac/mac_dl/mac_dl_ue_repository.h | 2 +- lib/mac/mac_ul/mac_ul_processor.h | 12 ++--- lib/mac/mac_ul/pdu_rx_handler.cpp | 12 ++--- lib/mac/mac_ul/pdu_rx_handler.h | 26 +++++------ lib/pcap/pcap_file_writer.h | 18 ++++---- lib/pcap/rlc_pcap_impl.cpp | 4 +- lib/pdcp/pdcp_pdu.h | 4 +- .../dft_processor_fftw_impl.h | 2 +- .../dft_processor_generic_impl.h | 2 +- lib/phy/support/prach_buffer_impl.h | 2 +- .../channel_coding/ldpc/ldpc_encoder_neon.cpp | 4 +- .../pusch/pusch_decoder_hw_impl.cpp | 2 +- .../dmrs_pdcch_processor_impl.cpp | 2 +- lib/phy/upper/vrb_to_prb_mapper.cpp | 4 +- lib/ran/band_helper.cpp | 8 ++-- .../resource_allocation_frequency.cpp | 2 +- lib/rlc/rlc_am_pdu.h | 2 +- lib/rrc/ue/procedures/rrc_ue_event_manager.h | 2 +- lib/ru/dummy/ru_dummy_rx_prach_buffer.h | 2 +- lib/scheduler/cell/cell_harq_manager.h | 4 +- .../common_scheduling/ra_scheduler.cpp | 4 +- .../config/sched_cell_config_helpers.cpp | 2 +- .../config/serving_cell_config_factory.cpp | 4 +- .../pucch_scheduling/pucch_allocator_impl.h | 2 +- lib/scheduler/slicing/slice_scheduler.cpp | 8 ++-- lib/scheduler/slicing/slice_scheduler.h | 2 +- lib/scheduler/slicing/slice_ue_repository.cpp | 2 +- .../support/pucch/pucch_default_resource.cpp | 4 +- lib/scheduler/ue_scheduling/harq_process.h | 6 +-- lib/scheduler/ue_scheduling/ue.cpp | 2 +- .../ue_scheduling/ue_cell_grid_allocator.cpp | 2 +- .../ul_logical_channel_manager.h | 2 +- .../benchmarks/du_high/du_high_benchmark.cpp | 2 +- tests/benchmarks/rlc/rlc_am_rx_benchmark.cpp | 2 +- .../scheduler_multi_ue_benchmark.cpp | 2 +- .../du_high/mac_test_mode_adapter_test.cpp | 1 + .../test_utils/du_high_worker_manager.h | 8 ++-- .../du_high_cu/cu_du_test.cpp | 3 +- .../du_high_cu/cu_multi_du_test.cpp | 2 +- .../du_high_cu/du_high_cu_test_simulator.cpp | 19 ++++---- .../du_high_cu/du_high_cu_test_simulator.h | 10 ++--- .../e2ap/e2ap_integration_test.cpp | 6 +-- .../pxsch_bler_test_channel_emulator.cpp | 10 ++--- .../pucch_res_test_builder_helper.cpp | 29 ++++++------ .../scheduler/pucch_res_test_builder_helper.h | 14 +++--- tests/unittests/adt/byte_buffer_test.cpp | 2 +- tests/unittests/cu_up/cu_up_test_helpers.h | 2 +- .../du_ran_resource_manager_test.cpp | 8 ++-- .../procedures/ue_configuration_test.cpp | 6 +-- tests/unittests/du_manager/sib_test.cpp | 7 +-- .../e1ap/common/e1ap_cu_up_test_messages.cpp | 18 ++++---- .../e1ap/common/e1ap_cu_up_test_messages.h | 13 +++--- .../e1ap/cu_up/e1ap_cu_up_test_helpers.cpp | 2 +- .../e1ap/cu_up/e1ap_cu_up_test_helpers.h | 2 +- tests/unittests/e2/common/e2_test_helpers.h | 22 ++++----- .../e2/e2ap_network_adapter_test.cpp | 2 +- .../e2/e2sm_kpm_meas_provider_test.cpp | 2 +- tests/unittests/e2/e2sm_kpm_test.cpp | 4 +- .../f1u/common/f1u_connector_test.cpp | 2 +- .../common/f1u_du_split_connector_test.cpp | 2 +- tests/unittests/gateways/sctp_test_helpers.h | 2 +- tests/unittests/mac/mac_ctrl_test_dummies.h | 4 +- .../mac/mac_rar_pdu_assembler_test.cpp | 4 +- tests/unittests/ngap/ngap_test_messages.h | 2 +- tests/unittests/rlc/rlc_rx_am_test.cpp | 4 +- .../scheduler/cell/cell_harq_manager_test.cpp | 4 +- .../scheduler/multiple_ue_sched_test.cpp | 14 +++--- .../scheduler_ue_fallback_mode_test.cpp | 8 ++-- .../slicing/slice_scheduler_test.cpp | 34 +++++++------- .../test_pucch_res_test_builder_helper.cpp | 2 +- .../scheduler/test_utils/config_generators.h | 2 +- .../uci_and_pucch/pucch_res_manager_test.cpp | 4 +- .../scheduler_uci_indication_test.cpp | 4 +- .../uci_and_pucch/uci_allocator_test.cpp | 2 +- .../uci_and_pucch/uci_test_utils.cpp | 4 +- .../ue_scheduling/ul_logical_channel_test.cpp | 2 +- .../support/unbounded_object_pool_test.cpp | 2 +- 212 files changed, 731 insertions(+), 633 deletions(-) delete mode 100644 include/srsran/ran/pci_helpers.h diff --git a/apps/du/du.cpp b/apps/du/du.cpp index 6cd06591cd..0b1c8f78c8 100644 --- a/apps/du/du.cpp +++ b/apps/du/du.cpp @@ -318,7 +318,7 @@ int main(int argc, char** argv) // Connect the forwarder to the metrics manager. metrics_notifier_forwarder.connect(metrics_mngr); - du& du_inst = *du_inst_and_cmds.unit; + srs_du::du& du_inst = *du_inst_and_cmds.unit; // Register the commands. app_services::stdin_command_dispatcher command_parser(*epoll_broker, du_inst_and_cmds.commands); diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 7598f9e253..03b49af8ae 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -424,7 +424,7 @@ int main(int argc, char** argv) auto du_inst_and_cmds = create_du(du_unit_cfg, du_dependencies); - du& du_inst = *du_inst_and_cmds.unit; + srs_du::du& du_inst = *du_inst_and_cmds.unit; // Only DU has metrics now. When CU returns metrics, create the vector of metrics as it is done for the commands. app_services::metrics_manager metrics_mngr( diff --git a/apps/services/worker_manager.cpp b/apps/services/worker_manager.cpp index b112a7d943..0b149af17f 100644 --- a/apps/services/worker_manager.cpp +++ b/apps/services/worker_manager.cpp @@ -285,17 +285,17 @@ void worker_manager::create_du_executors(bool is_blocking_m // DU-high executor mapper. using exec_list = std::initializer_list; - auto cell_exec_mapper = std::make_unique(exec_list{exec_map.at("cell_exec#" + cell_id_str)}, - exec_list{exec_map.at("slot_exec#" + cell_id_str)}); + auto cell_exec_mapper = std::make_unique( + exec_list{exec_map.at("cell_exec#" + cell_id_str)}, exec_list{exec_map.at("slot_exec#" + cell_id_str)}); auto ue_exec_mapper = - std::make_unique(exec_list{exec_map.at(fmt::format("du_rb_prio_exec#{}", i))}, - exec_list{exec_map.at(fmt::format("du_rb_ul_exec#{}", i))}, - exec_list{exec_map.at(fmt::format("du_rb_dl_exec#{}", i))}); - du_item.du_high_exec_mapper = std::make_unique(std::move(cell_exec_mapper), - std::move(ue_exec_mapper), - *exec_map.at("ctrl_exec"), - *exec_map.at("timer_exec"), - *exec_map.at("ctrl_exec")); + std::make_unique(exec_list{exec_map.at(fmt::format("du_rb_prio_exec#{}", i))}, + exec_list{exec_map.at(fmt::format("du_rb_ul_exec#{}", i))}, + exec_list{exec_map.at(fmt::format("du_rb_dl_exec#{}", i))}); + du_item.du_high_exec_mapper = std::make_unique(std::move(cell_exec_mapper), + std::move(ue_exec_mapper), + *exec_map.at("ctrl_exec"), + *exec_map.at("timer_exec"), + *exec_map.at("ctrl_exec")); } const du_low_unit_expert_threads_config& upper_phy_threads_cfg = du_low.expert_execution_cfg.threads; @@ -784,7 +784,7 @@ void worker_manager::create_ru_executors( radio_exec = exec_mng.executors().at("ru_dummy"); } -du_high_executor_mapper& worker_manager::get_du_high_executor_mapper(unsigned du_index) +srs_du::du_high_executor_mapper& worker_manager::get_du_high_executor_mapper(unsigned du_index) { srsran_assert(du_index < du_high_executors.size(), "Invalid DU index"); return *du_high_executors[du_index].du_high_exec_mapper; diff --git a/apps/services/worker_manager.h b/apps/services/worker_manager.h index f183c67d2f..e6b9d88ef0 100644 --- a/apps/services/worker_manager.h +++ b/apps/services/worker_manager.h @@ -71,7 +71,7 @@ struct worker_manager : public worker_manager_executor_getter { std::unique_ptr cu_up_exec_mapper; - du_high_executor_mapper& get_du_high_executor_mapper(unsigned du_index); + srs_du::du_high_executor_mapper& get_du_high_executor_mapper(unsigned du_index); // Gets the DU-low downlink executors. void get_du_low_dl_executors(std::vector& executors, unsigned sector_id) const; @@ -91,7 +91,7 @@ struct worker_manager : public worker_manager_executor_getter { static const unsigned nof_cu_up_ue_strands = 16; struct du_high_executor_storage { - std::unique_ptr du_high_exec_mapper; + std::unique_ptr du_high_exec_mapper; }; std::vector du_high_executors; std::vector> du_low_dl_executors; diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index 25eba276f6..187d387bfc 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -215,11 +215,11 @@ static void fill_csi_resources(serving_cell_config& out_cell, const du_high_unit out_cell.init_dl_bwp.pdsch_cfg->p_zp_csi_rs_res = csi_helper::make_periodic_zp_csi_rs_resource_set(csi_params); } -std::vector srsran::generate_du_cell_config(const du_high_unit_config& config) +std::vector srsran::generate_du_cell_config(const du_high_unit_config& config) { srslog::basic_logger& logger = srslog::fetch_basic_logger("GNB", false); - std::vector out_cfg; + std::vector out_cfg; out_cfg.reserve(config.cells_cfg.size()); for (const auto& cell : config.cells_cfg) { @@ -282,7 +282,7 @@ std::vector srsran::generate_du_cell_config(const du_high_unit_c // Create the configuration. out_cfg.push_back(config_helpers::make_default_du_cell_config(param)); - du_cell_config& out_cell = out_cfg.back(); + srs_du::du_cell_config& out_cell = out_cfg.back(); // Set the rest of the parameters. out_cell.nr_cgi.plmn_id = plmn_identity::parse(base_cell.plmn).value(); @@ -515,25 +515,25 @@ std::vector srsran::generate_du_cell_config(const du_high_unit_c } // Parameters for PUCCH-Config builder (these parameters will be used later on to generate the PUCCH resources). - pucch_builder_params& du_pucch_cfg = out_cell.pucch_cfg; + srs_du::pucch_builder_params& du_pucch_cfg = out_cell.pucch_cfg; const du_high_unit_pucch_config& user_pucch_cfg = base_cell.pucch_cfg; du_pucch_cfg.nof_cell_harq_pucch_res_sets = user_pucch_cfg.nof_cell_harq_pucch_sets; du_pucch_cfg.nof_sr_resources = user_pucch_cfg.nof_cell_sr_resources; du_pucch_cfg.nof_csi_resources = user_pucch_cfg.nof_cell_csi_resources; if (user_pucch_cfg.use_format_0) { - auto& f0_params = du_pucch_cfg.f0_or_f1_params.emplace(); + auto& f0_params = du_pucch_cfg.f0_or_f1_params.emplace(); // Subtract 2 PUCCH resources from value: with Format 0, 2 extra resources will be added by the DU resource // allocator when the DU create the UE configuration. du_pucch_cfg.nof_ue_pucch_f0_or_f1_res_harq = user_pucch_cfg.nof_ue_pucch_res_harq_per_set - 2U; du_pucch_cfg.nof_ue_pucch_f2_res_harq = user_pucch_cfg.nof_ue_pucch_res_harq_per_set - 2U; f0_params.intraslot_freq_hopping = user_pucch_cfg.f0_intraslot_freq_hopping; } else { - auto& f1_params = du_pucch_cfg.f0_or_f1_params.emplace(); + auto& f1_params = du_pucch_cfg.f0_or_f1_params.emplace(); du_pucch_cfg.nof_ue_pucch_f0_or_f1_res_harq = user_pucch_cfg.nof_ue_pucch_res_harq_per_set; du_pucch_cfg.nof_ue_pucch_f2_res_harq = user_pucch_cfg.nof_ue_pucch_res_harq_per_set; f1_params.occ_supported = user_pucch_cfg.f1_enable_occ; - f1_params.nof_cyc_shifts = static_cast(user_pucch_cfg.nof_cyclic_shift); - f1_params.intraslot_freq_hopping = user_pucch_cfg.f1_intraslot_freq_hopping; + f1_params.nof_cyc_shifts = static_cast(user_pucch_cfg.nof_cyclic_shift); + f1_params.intraslot_freq_hopping = user_pucch_cfg.f1_intraslot_freq_hopping; } du_pucch_cfg.f2_params.max_code_rate = user_pucch_cfg.max_code_rate; du_pucch_cfg.f2_params.max_nof_rbs = user_pucch_cfg.f2_max_nof_rbs; @@ -541,7 +541,7 @@ std::vector srsran::generate_du_cell_config(const du_high_unit_c du_pucch_cfg.f2_params.max_payload_bits = user_pucch_cfg.max_payload_bits; // Parameters for SRS-Config. - srs_builder_params& du_srs_cfg = out_cell.srs_cfg; + srs_du::srs_builder_params& du_srs_cfg = out_cell.srs_cfg; const du_high_unit_srs_config& user_srs_cfg = base_cell.srs_cfg; du_srs_cfg.srs_enabled = user_srs_cfg.srs_enabled; du_srs_cfg.max_nof_symbols = user_srs_cfg.max_nof_symbols_per_slot; @@ -713,9 +713,9 @@ srsran::generate_du_slicing_rrm_policy_config(span return rrm_policy_cfgs; } -std::map srsran::generate_du_qos_config(const du_high_unit_config& config) +std::map srsran::generate_du_qos_config(const du_high_unit_config& config) { - std::map out_cfg = {}; + std::map out_cfg = {}; if (config.qos_cfg.empty()) { out_cfg = config_helpers::make_default_du_qos_config_list(config.warn_on_drop, config.metrics.rlc.report_period); return out_cfg; @@ -765,12 +765,12 @@ std::map srsran::generate_du_qos_config(const du_high_ return out_cfg; } -std::map srsran::generate_du_srb_config(const du_high_unit_config& config) +std::map srsran::generate_du_srb_config(const du_high_unit_config& config) { - std::map srb_cfg; + std::map srb_cfg; // SRB1 - srb_cfg.insert(std::make_pair(srb_id_t::srb1, du_srb_config{})); + srb_cfg.insert(std::make_pair(srb_id_t::srb1, srs_du::du_srb_config{})); if (config.srb_cfg.find(srb_id_t::srb1) != config.srb_cfg.end()) { auto& out_rlc = srb_cfg[srb_id_t::srb1].rlc; auto& out_mac = srb_cfg[srb_id_t::srb1].mac; @@ -783,7 +783,7 @@ std::map srsran::generate_du_srb_config(const du_high_u } // SRB2 - srb_cfg.insert(std::make_pair(srb_id_t::srb2, du_srb_config{})); + srb_cfg.insert(std::make_pair(srb_id_t::srb2, srs_du::du_srb_config{})); if (config.srb_cfg.find(srb_id_t::srb2) != config.srb_cfg.end()) { auto& out_rlc = srb_cfg[srb_id_t::srb2].rlc; auto& out_mac = srb_cfg[srb_id_t::srb2].mac; @@ -796,7 +796,7 @@ std::map srsran::generate_du_srb_config(const du_high_u } // SRB3 - srb_cfg.insert(std::make_pair(srb_id_t::srb3, du_srb_config{})); + srb_cfg.insert(std::make_pair(srb_id_t::srb3, srs_du::du_srb_config{})); if (config.srb_cfg.find(srb_id_t::srb3) != config.srb_cfg.end()) { auto& out_rlc = srb_cfg[srb_id_t::srb3].rlc; auto& out_mac = srb_cfg[srb_id_t::srb3].mac; @@ -897,7 +897,7 @@ scheduler_expert_config srsran::generate_scheduler_expert_config(const du_high_u e2ap_configuration srsran::generate_e2_config(const du_high_unit_config& du_high) { - e2ap_configuration out_cfg = srsran::config_helpers::make_default_e2ap_config(); + e2ap_configuration out_cfg = config_helpers::make_default_e2ap_config(); out_cfg.gnb_id = du_high.gnb_id; out_cfg.plmn = du_high.cells_cfg.front().cell.plmn; out_cfg.gnb_du_id = du_high.gnb_du_id; @@ -907,7 +907,7 @@ e2ap_configuration srsran::generate_e2_config(const du_high_unit_config& du_high return out_cfg; } -void srsran::ntn_augment_rlc_parameters(const ntn_config& ntn_cfg, std::map& srb_cfgs) +void srsran::ntn_augment_rlc_parameters(const ntn_config& ntn_cfg, std::map& srb_cfgs) { // NTN is enabled, so we need to augment the RLC parameters for the NTN cell. for (auto& srb : srb_cfgs) { diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.h b/apps/units/flexible_du/du_high/du_high_config_translators.h index 6537dfd94d..3f243d1f9d 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.h +++ b/apps/units/flexible_du/du_high/du_high_config_translators.h @@ -26,13 +26,13 @@ namespace srsran { struct du_high_unit_config; /// Converts and returns the given gnb application configuration to a DU cell configuration. -std::vector generate_du_cell_config(const du_high_unit_config& config); +std::vector generate_du_cell_config(const du_high_unit_config& config); /// Converts and returns the given gnb application QoS configuration to a DU QoS list configuration. -std::map generate_du_qos_config(const du_high_unit_config& config); +std::map generate_du_qos_config(const du_high_unit_config& config); /// Converts and returns the given gnb application QoS configuration to a DU SRB list configuration. -std::map generate_du_srb_config(const du_high_unit_config& config); +std::map generate_du_srb_config(const du_high_unit_config& config); /// Converts and returns the given gnb application configuration to a mac expert configuration. mac_expert_config generate_mac_expert_config(const du_high_unit_config& config); @@ -44,7 +44,7 @@ scheduler_expert_config generate_scheduler_expert_config(const du_high_unit_conf e2ap_configuration generate_e2_config(const du_high_unit_config& du_high); /// Augments RLC parameters based on NTN configuration. -void ntn_augment_rlc_parameters(const ntn_config& ntn_cfg, std::map& srb_cfgs); +void ntn_augment_rlc_parameters(const ntn_config& ntn_cfg, std::map& srb_cfgs); /// Converts and returns the given gnb application configuration to a DU slice RRM policy configuration list. std::vector diff --git a/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp b/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp index 9919b79745..c376ebcb92 100644 --- a/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp +++ b/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.cpp @@ -129,19 +129,19 @@ static rlc_metrics_notifier* build_rlc_du_metrics(std::vector, std::vector>> -srsran::fill_du_high_wrapper_config(du_high_wrapper_config& out_cfg, - const du_high_unit_config& du_high_unit_cfg, - unsigned du_idx, - du_high_executor_mapper& execution_mapper, - srs_du::f1c_connection_client& f1c_client_handler, - srs_du::f1u_du_gateway& f1u_gw, - timer_manager& timer_mng, - mac_pcap& mac_p, - rlc_pcap& rlc_p, - e2_connection_client& e2_client_handler, - e2_metric_connector_manager& e2_metric_connectors, - srslog::sink& json_sink, - app_services::metrics_notifier& metrics_notifier) +srsran::fill_du_high_wrapper_config(srs_du::du_high_wrapper_config& out_cfg, + const du_high_unit_config& du_high_unit_cfg, + unsigned du_idx, + srs_du::du_high_executor_mapper& execution_mapper, + srs_du::f1c_connection_client& f1c_client_handler, + srs_du::f1u_du_gateway& f1u_gw, + timer_manager& timer_mng, + mac_pcap& mac_p, + rlc_pcap& rlc_p, + e2_connection_client& e2_client_handler, + e2_metric_connector_manager& e2_metric_connectors, + srslog::sink& json_sink, + app_services::metrics_notifier& metrics_notifier) { // DU-high configuration. srs_du::du_high_configuration& du_hi_cfg = out_cfg.du_hi; diff --git a/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h b/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h index c96f24ca6d..bc251feb20 100644 --- a/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h +++ b/apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h @@ -20,37 +20,37 @@ class metrics_notifier; } namespace srs_du { -class f1u_du_gateway; +class du_high_executor_mapper; +struct du_high_wrapper_config; +struct du_high_wrapper_dependencies; class f1c_connection_client; +class f1u_du_gateway; } // namespace srs_du -class du_high_executor_mapper; class e2_metric_connector_manager; class e2_connection_client; class mac_pcap; class rlc_pcap; class timer_manager; struct du_high_unit_config; -struct du_high_wrapper_config; -struct du_high_wrapper_dependencies; /// Set up sources for the DU high metrics. void announce_du_high_cells(const du_high_unit_config& du_high_unit_cfg); /// Fills the given DU high wrapper configuration. std::pair, std::vector>> -fill_du_high_wrapper_config(du_high_wrapper_config& out_cfg, - const du_high_unit_config& du_high_unit_cfg, - unsigned du_idx, - du_high_executor_mapper& execution_mapper, - srs_du::f1c_connection_client& f1c_client_handler, - srs_du::f1u_du_gateway& f1u_gw, - timer_manager& timer_mng, - mac_pcap& mac_p, - rlc_pcap& rlc_p, - e2_connection_client& e2_client_handler, - e2_metric_connector_manager& e2_metric_connectors, - srslog::sink& json_sink, - app_services::metrics_notifier& metrics_notifier); +fill_du_high_wrapper_config(srs_du::du_high_wrapper_config& out_cfg, + const du_high_unit_config& du_high_unit_cfg, + unsigned du_idx, + srs_du::du_high_executor_mapper& execution_mapper, + srs_du::f1c_connection_client& f1c_client_handler, + srs_du::f1u_du_gateway& f1u_gw, + timer_manager& timer_mng, + mac_pcap& mac_p, + rlc_pcap& rlc_p, + e2_connection_client& e2_client_handler, + e2_metric_connector_manager& e2_metric_connectors, + srslog::sink& json_sink, + app_services::metrics_notifier& metrics_notifier); } // namespace srsran diff --git a/apps/units/flexible_du/du_low/du_low_config_translator.cpp b/apps/units/flexible_du/du_low/du_low_config_translator.cpp index c012ac3e9d..84e4252175 100644 --- a/apps/units/flexible_du/du_low/du_low_config_translator.cpp +++ b/apps/units/flexible_du/du_low/du_low_config_translator.cpp @@ -17,18 +17,18 @@ using namespace srsran; -static void generate_du_low_config(du_low_config& out_config, - const du_low_unit_config& du_low, - const hal_upper_phy_config& hal_config, - span du_cells, - span max_puschs_per_slot, - unsigned du_id) +static void generate_du_low_config(srs_du::du_low_config& out_config, + const du_low_unit_config& du_low, + const hal_upper_phy_config& hal_config, + span du_cells, + span max_puschs_per_slot, + unsigned du_id) { out_config.cells.reserve(du_cells.size()); for (unsigned i = 0, e = du_cells.size(); i != e; ++i) { - const du_cell_config& cell = du_cells[i]; - upper_phy_config& upper_phy_cell = out_config.cells.emplace_back().upper_phy_cfg; + const srs_du::du_cell_config& cell = du_cells[i]; + upper_phy_config& upper_phy_cell = out_config.cells.emplace_back().upper_phy_cfg; // Initialize the HAL config of the upper PHY. upper_phy_cell.hal_config = hal_config; @@ -159,13 +159,13 @@ static void generate_du_low_config(du_low_config& out_config, } } -void srsran::generate_du_low_wrapper_config(du_low_wrapper_config& out_config, - const du_low_unit_config& du_low_unit_cfg, - const hal_upper_phy_config& hal_config, - std::vector prach_ports, - span du_cells, - span max_puschs_per_slot, - unsigned du_id) +void srsran::generate_du_low_wrapper_config(srs_du::du_low_wrapper_config& out_config, + const du_low_unit_config& du_low_unit_cfg, + const hal_upper_phy_config& hal_config, + std::vector prach_ports, + span du_cells, + span max_puschs_per_slot, + unsigned du_id) { generate_du_low_config(out_config.du_low_cfg, du_low_unit_cfg, hal_config, du_cells, max_puschs_per_slot, du_id); out_config.prach_ports = std::move(prach_ports); diff --git a/apps/units/flexible_du/du_low/du_low_config_translator.h b/apps/units/flexible_du/du_low/du_low_config_translator.h index 650fc24ddb..a123b0ed2b 100644 --- a/apps/units/flexible_du/du_low/du_low_config_translator.h +++ b/apps/units/flexible_du/du_low/du_low_config_translator.h @@ -15,16 +15,19 @@ namespace srsran { +namespace srs_du { struct du_cell_config; struct du_low_config; +} // namespace srs_du + struct du_low_unit_config; -void generate_du_low_wrapper_config(du_low_wrapper_config& out_config, - const du_low_unit_config& du_low_unit_cfg, - const hal_upper_phy_config& hal_config, - std::vector prach_ports, - span du_cells, - span max_puschs_per_slot, - unsigned du_id); +void generate_du_low_wrapper_config(srs_du::du_low_wrapper_config& out_config, + const du_low_unit_config& du_low_unit_cfg, + const hal_upper_phy_config& hal_config, + std::vector prach_ports, + span du_cells, + span max_puschs_per_slot, + unsigned du_id); } // namespace srsran diff --git a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp index f745eb159e..da9221655c 100644 --- a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp +++ b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp @@ -51,16 +51,16 @@ static void generate_dl_processor_config(downlink_processor_factory_sw_config& o } void srsran::make_du_low_wrapper_config_and_dependencies( - du_low_wrapper_config& out_cfg, - const du_low_unit_config& du_low_unit_cfg, - const hal_upper_phy_config& hal_config, - std::vector prach_ports, - span du_cells, - span max_puschs_per_slot, - upper_phy_rg_gateway& rg_gateway, - upper_phy_rx_symbol_request_notifier& rx_symbol_request_notifier, - worker_manager& workers, - unsigned du_id) + srs_du::du_low_wrapper_config& out_cfg, + const du_low_unit_config& du_low_unit_cfg, + const hal_upper_phy_config& hal_config, + std::vector prach_ports, + span du_cells, + span max_puschs_per_slot, + upper_phy_rg_gateway& rg_gateway, + upper_phy_rx_symbol_request_notifier& rx_symbol_request_notifier, + worker_manager& workers, + unsigned du_id) { out_cfg.du_low_cfg.logger = &srslog::fetch_basic_logger("DU"); @@ -69,7 +69,7 @@ void srsran::make_du_low_wrapper_config_and_dependencies( // Fill the workers information. for (unsigned i = 0, e = out_cfg.du_low_cfg.cells.size(); i != e; ++i) { - du_low_cell_config& cell = out_cfg.du_low_cfg.cells[i]; + srs_du::du_low_cell_config& cell = out_cfg.du_low_cfg.cells[i]; generate_dl_processor_config(cell.dl_proc_cfg, du_low_unit_cfg, diff --git a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h index b179385c6b..4b3f19561b 100644 --- a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h +++ b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h @@ -15,19 +15,22 @@ namespace srsran { -struct worker_manager; +namespace srs_du { struct du_cell_config; +} + struct du_low_unit_config; +struct worker_manager; -void make_du_low_wrapper_config_and_dependencies(du_low_wrapper_config& out_cfg, - const du_low_unit_config& du_low_unit_cfg, - const hal_upper_phy_config& hal_config, - std::vector prach_ports, - span du_cells, - span max_puschs_per_slot, - upper_phy_rg_gateway& rg_gateway, - upper_phy_rx_symbol_request_notifier& rx_symbol_request_notifier, - worker_manager& workers, - unsigned du_id); +void make_du_low_wrapper_config_and_dependencies(srs_du::du_low_wrapper_config& out_cfg, + const du_low_unit_config& du_low_unit_cfg, + const hal_upper_phy_config& hal_config, + std::vector prach_ports, + span du_cells, + span max_puschs_per_slot, + upper_phy_rg_gateway& rg_gateway, + upper_phy_rx_symbol_request_notifier& rx_symbol_request_notifier, + worker_manager& workers, + unsigned du_id); } // namespace srsran diff --git a/apps/units/flexible_du/du_unit.h b/apps/units/flexible_du/du_unit.h index f84d5817de..7cf84543fd 100644 --- a/apps/units/flexible_du/du_unit.h +++ b/apps/units/flexible_du/du_unit.h @@ -36,7 +36,7 @@ struct worker_manager; /// Wraps the DU and its supported application commands. struct du_unit { - std::unique_ptr unit; + std::unique_ptr unit; std::vector> commands; std::vector metrics; }; diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.cpp b/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.cpp index ef22a0dfea..eb96514907 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.cpp +++ b/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.cpp @@ -64,12 +64,12 @@ tx_timing_window_params_us_to_symbols(std::chrono::microseconds T return tx_window_timing_params; } -static void generate_config(ru_ofh_configuration& out_cfg, - const ru_ofh_unit_config& ru_cfg, - span du_cells, - unsigned max_processing_delay_slots) +static void generate_config(ru_ofh_configuration& out_cfg, + const ru_ofh_unit_config& ru_cfg, + span du_cells, + unsigned max_processing_delay_slots) { - /// Individual Open Fronthaul sector configurations. + // Individual Open Fronthaul sector configurations. std::vector sector_configs; out_cfg.gps_Alpha = ru_cfg.gps_Alpha; @@ -81,7 +81,7 @@ static void generate_config(ru_ofh_configuration& out_cfg, // Add one cell. for (unsigned i = 0, e = ru_cfg.cells.size(); i != e; ++i) { const ru_ofh_unit_cell_config& cell_cfg = ru_cfg.cells[i]; - const du_cell_config& du_cell_cfg = du_cells[i]; + const srs_du::du_cell_config& du_cell_cfg = du_cells[i]; out_cfg.sector_configs.emplace_back(); ru_ofh_sector_configuration& sector_cfg = out_cfg.sector_configs.back(); @@ -143,9 +143,9 @@ static void generate_config(ru_ofh_configuration& out_cfg, } } -ru_ofh_configuration srsran::generate_ru_ofh_config(const ru_ofh_unit_config& ru_cfg, - span du_cells, - unsigned max_processing_delay_slots) +ru_ofh_configuration srsran::generate_ru_ofh_config(const ru_ofh_unit_config& ru_cfg, + span du_cells, + unsigned max_processing_delay_slots) { ru_ofh_configuration out_cfg; generate_config(out_cfg, ru_cfg, du_cells, max_processing_delay_slots); diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.h b/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.h index 04337a3294..19ff4c090c 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.h +++ b/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.h @@ -14,13 +14,16 @@ namespace srsran { +namespace srs_du { struct du_cell_config; +} + struct ru_ofh_unit_config; /// Converts and returns the given Open Fronthaul Radio Unit application unit configuration to a Open Fronthaul Radio /// Unit configuration. -ru_ofh_configuration generate_ru_ofh_config(const ru_ofh_unit_config& ru_cfg, - span du_cells, - unsigned max_processing_delay_slots); +ru_ofh_configuration generate_ru_ofh_config(const ru_ofh_unit_config& ru_cfg, + span du_cells, + unsigned max_processing_delay_slots); } // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_factories.h b/apps/units/flexible_du/split_7_2/ru_ofh_factories.h index 99efc1f5d8..2e62c9d425 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_factories.h +++ b/apps/units/flexible_du/split_7_2/ru_ofh_factories.h @@ -20,13 +20,15 @@ class ru_uplink_plane_rx_symbol_notifier; class ru_timing_notifier; class ru_error_notifier; +namespace srs_du { struct du_cell_config; +} /// Open Fronthaul RU factory configuration. struct ru_ofh_factory_config { - ru_ofh_unit_config ru_cfg; - unsigned max_processing_delay_slots; - span du_cells; + ru_ofh_unit_config ru_cfg; + unsigned max_processing_delay_slots; + span du_cells; }; /// Open Fronthaul RU factory dependencies. diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp b/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp index bf216fb792..a10ed25670 100644 --- a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp +++ b/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp @@ -20,9 +20,9 @@ using namespace srsran; static constexpr cyclic_prefix cp = cyclic_prefix::NORMAL; /// Fills the given low PHY configuration from the given gnb configuration. -static lower_phy_configuration generate_low_phy_config(const du_cell_config& config, - const ru_sdr_unit_config& ru_cfg, - unsigned max_processing_delay_slot) +static lower_phy_configuration generate_low_phy_config(const srs_du::du_cell_config& config, + const ru_sdr_unit_config& ru_cfg, + unsigned max_processing_delay_slot) { lower_phy_configuration out_cfg; @@ -152,9 +152,9 @@ static double calibrate_center_freq_Hz(double center_freq_Hz, double freq_offset return (center_freq_Hz + freq_offset_Hz) * (1.0 + calibration_ppm * 1e-6); } -static void generate_radio_config(radio_configuration::radio& out_cfg, - const ru_sdr_unit_config& ru_cfg, - span du_cells) +static void generate_radio_config(radio_configuration::radio& out_cfg, + const ru_sdr_unit_config& ru_cfg, + span du_cells) { out_cfg.args = ru_cfg.device_arguments; out_cfg.log_level = ru_cfg.loggers.radio_level; @@ -171,7 +171,7 @@ static void generate_radio_config(radio_configuration::radio& out_cfg, // For each sector... for (unsigned sector_id = 0; sector_id != du_cells.size(); ++sector_id) { // Select cell configuration. - const du_cell_config& cell = du_cells[sector_id]; + const srs_du::du_cell_config& cell = du_cells[sector_id]; // Each cell is mapped to a different stream. radio_configuration::stream tx_stream_config; @@ -243,9 +243,9 @@ static void generate_radio_config(radio_configuration::radio& out_cfg, } } -ru_generic_configuration srsran::generate_ru_sdr_config(const ru_sdr_unit_config& ru_cfg, - span du_cells, - unsigned max_processing_delay_slots) +ru_generic_configuration srsran::generate_ru_sdr_config(const ru_sdr_unit_config& ru_cfg, + span du_cells, + unsigned max_processing_delay_slots) { ru_generic_configuration out_cfg; out_cfg.device_driver = ru_cfg.device_driver; @@ -256,4 +256,4 @@ ru_generic_configuration srsran::generate_ru_sdr_config(const ru_sdr_unit_config } return out_cfg; -} \ No newline at end of file +} diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_translator.h b/apps/units/flexible_du/split_8/ru_sdr_config_translator.h index ea12258590..3f200b80d8 100644 --- a/apps/units/flexible_du/split_8/ru_sdr_config_translator.h +++ b/apps/units/flexible_du/split_8/ru_sdr_config_translator.h @@ -14,12 +14,14 @@ namespace srsran { +namespace srs_du { struct du_cell_config; +} struct ru_sdr_unit_config; /// Converts and returns the given RU SDR application unit configuration to a SDR RU configuration. -ru_generic_configuration generate_ru_sdr_config(const ru_sdr_unit_config& ru_cfg, - span du_cells, - unsigned max_processing_delay_slots); +ru_generic_configuration generate_ru_sdr_config(const ru_sdr_unit_config& ru_cfg, + span du_cells, + unsigned max_processing_delay_slots); } // namespace srsran diff --git a/apps/units/flexible_du/split_8/ru_sdr_factories.h b/apps/units/flexible_du/split_8/ru_sdr_factories.h index 9d746251a4..a67cb1824f 100644 --- a/apps/units/flexible_du/split_8/ru_sdr_factories.h +++ b/apps/units/flexible_du/split_8/ru_sdr_factories.h @@ -16,7 +16,10 @@ namespace srsran { +namespace srs_du { struct du_cell_config; +} // namespace srs_du + struct du_high_unit_config; class ru_uplink_plane_rx_symbol_notifier; class ru_timing_notifier; @@ -25,9 +28,9 @@ struct worker_manager; /// SDR RU factory configuration. struct ru_sdr_factory_config { - ru_sdr_unit_config ru_cfg; - unsigned max_processing_delay_slots; - span du_cells; + ru_sdr_unit_config ru_cfg; + unsigned max_processing_delay_slots; + span du_cells; }; /// SDR RU factory dependencies. diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp index cda1d39190..65a606fff6 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp @@ -38,7 +38,7 @@ static std::unique_ptr create_dummy_radio_unit(const ru_dummy_unit_c unsigned max_processing_delay_slots, unsigned nof_prach_ports, worker_manager& workers, - span du_cells, + span du_cells, ru_uplink_plane_rx_symbol_notifier& symbol_notifier, ru_timing_notifier& timing_notifier, ru_error_notifier& error_notifier) @@ -56,7 +56,7 @@ static std::unique_ptr create_dummy_radio_unit(const ru_dummy_unit_c static std::unique_ptr create_radio_unit(const std::variant& ru_cfg, worker_manager& workers, - span du_cells, + span du_cells, ru_uplink_plane_rx_symbol_notifier& symbol_notifier, ru_timing_notifier& timing_notifier, ru_error_notifier& error_notifier, @@ -146,11 +146,11 @@ du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_depe auto du_cells = generate_du_cell_config(du_hi); - std::vector> du_insts; - auto du_impl = std::make_unique(du_cells.size()); + std::vector> du_insts; + auto du_impl = std::make_unique(du_cells.size()); - std::vector prach_ports; - std::vector max_pusch_per_slot; + std::vector prach_ports; + std::vector max_pusch_per_slot; for (const auto& high : du_hi.cells_cfg) { prach_ports.push_back(high.cell.prach_cfg.ports); max_pusch_per_slot.push_back(high.cell.pusch_cfg.max_puschs_per_slot); @@ -233,8 +233,8 @@ du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_depe for (unsigned i = 0, e = du_cells.size(); i != e; ++i) { // Create one DU per cell. - du_wrapper_config du_cfg = {}; - du_high_unit_config tmp_cfg = du_hi; + srs_du::du_wrapper_config du_cfg = {}; + du_high_unit_config tmp_cfg = du_hi; tmp_cfg.cells_cfg.resize(1); tmp_cfg.cells_cfg[0] = du_hi.cells_cfg[i]; @@ -242,7 +242,7 @@ du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_depe du_lo, hal_config, {prach_ports[i]}, - span(&du_cells[i], 1), + span(&du_cells[i], 1), span(&max_pusch_per_slot[i], 1), du_impl->get_upper_ru_dl_rg_adapter(), du_impl->get_upper_ru_ul_request_adapter(), diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp index 59bf6e0979..ee85e46ee2 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp @@ -51,7 +51,7 @@ void dynamic_du_impl::add_ru(std::unique_ptr active_ru) ru_ul_request_adapt.connect(ru->get_uplink_plane_handler()); } -void dynamic_du_impl::add_dus(std::vector> active_du) +void dynamic_du_impl::add_dus(std::vector> active_du) { du_list = std::move(active_du); srsran_assert(!du_list.empty(), "Cannot set an empty DU list"); diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h index 21629dd3c5..2f117116f4 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h @@ -20,7 +20,7 @@ namespace srsran { class radio_unit; -class dynamic_du_impl : public du +class dynamic_du_impl : public srs_du::du { public: explicit dynamic_du_impl(unsigned nof_cells); @@ -35,7 +35,7 @@ class dynamic_du_impl : public du void add_ru(std::unique_ptr active_ru); /// Adds the given DUs to this dynamic DU. - void add_dus(std::vector> active_du); + void add_dus(std::vector> active_du); /// Getters to the adaptors. upper_ru_ul_adapter& get_upper_ru_ul_adapter() { return ru_ul_adapt; } @@ -45,13 +45,13 @@ class dynamic_du_impl : public du upper_ru_ul_request_adapter& get_upper_ru_ul_request_adapter() { return ru_ul_request_adapt; } private: - upper_ru_ul_adapter ru_ul_adapt; - upper_ru_timing_adapter ru_timing_adapt; - upper_ru_error_adapter ru_error_adapt; - std::vector> du_list; - std::unique_ptr ru; - upper_ru_dl_rg_adapter ru_dl_rg_adapt; - upper_ru_ul_request_adapter ru_ul_request_adapt; + upper_ru_ul_adapter ru_ul_adapt; + upper_ru_timing_adapter ru_timing_adapt; + upper_ru_error_adapter ru_error_adapt; + std::vector> du_list; + std::unique_ptr ru; + upper_ru_dl_rg_adapter ru_dl_rg_adapt; + upper_ru_ul_request_adapter ru_ul_request_adapt; }; } // namespace srsran diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp index 713c37259c..db173200d0 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp @@ -14,14 +14,14 @@ using namespace srsran; -ru_dummy_configuration srsran::generate_ru_dummy_config(const ru_dummy_unit_config& ru_cfg, - span du_cells, - unsigned max_processing_delay_slots, - unsigned nof_prach_ports) +ru_dummy_configuration srsran::generate_ru_dummy_config(const ru_dummy_unit_config& ru_cfg, + span du_cells, + unsigned max_processing_delay_slots, + unsigned nof_prach_ports) { ru_dummy_configuration out_cfg; - const du_cell_config& cell = du_cells.front(); + const srs_du::du_cell_config& cell = du_cells.front(); // Derive parameters. unsigned channel_bw_prb = band_helper::get_n_rbs_from_bw( diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h index 11ff04599a..9f2b97b07f 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h @@ -15,13 +15,16 @@ namespace srsran { +namespace srs_du { struct du_cell_config; +} + struct ru_dummy_unit_config; /// Generates the dummy RU configuration from the given application unit configuration. -ru_dummy_configuration generate_ru_dummy_config(const ru_dummy_unit_config& ru_cfg, - span du_cells, - unsigned max_processing_delay_slots, - unsigned nof_prach_ports); +ru_dummy_configuration generate_ru_dummy_config(const ru_dummy_unit_config& ru_cfg, + span du_cells, + unsigned max_processing_delay_slots, + unsigned nof_prach_ports); } // namespace srsran diff --git a/include/srsran/adt/bounded_bitset.h b/include/srsran/adt/bounded_bitset.h index 68fd1a6a10..29e83dda6e 100644 --- a/include/srsran/adt/bounded_bitset.h +++ b/include/srsran/adt/bounded_bitset.h @@ -1079,7 +1079,7 @@ class bounded_bitset friend struct fmt::formatter>; // Capacity of the underlying array in number of words. - constexpr static size_t max_nof_words_() noexcept { return (N + bits_per_word - 1) / bits_per_word; } + static constexpr size_t max_nof_words_() noexcept { return (N + bits_per_word - 1) / bits_per_word; } std::array buffer = {0}; size_t cur_size = 0; diff --git a/include/srsran/adt/byte_buffer.h b/include/srsran/adt/byte_buffer.h index c24229ded5..c14bb2e3d6 100644 --- a/include/srsran/adt/byte_buffer.h +++ b/include/srsran/adt/byte_buffer.h @@ -181,7 +181,7 @@ class byte_buffer }; /// Headroom given to the first segment of the byte_buffer. - constexpr static size_t DEFAULT_FIRST_SEGMENT_HEADROOM = 16; + static constexpr size_t DEFAULT_FIRST_SEGMENT_HEADROOM = 16; public: using value_type = uint8_t; diff --git a/include/srsran/adt/detail/type_storage.h b/include/srsran/adt/detail/type_storage.h index 48da6ea2df..02ca10e009 100644 --- a/include/srsran/adt/detail/type_storage.h +++ b/include/srsran/adt/detail/type_storage.h @@ -64,8 +64,8 @@ struct type_storage { return addr(); } - constexpr static size_t obj_size = sizeof(T) > MinSize ? sizeof(T) : MinSize; - constexpr static size_t align_size = alignof(T) > AlignSize ? alignof(T) : AlignSize; + static constexpr size_t obj_size = sizeof(T) > MinSize ? sizeof(T) : MinSize; + static constexpr size_t align_size = alignof(T) > AlignSize ? alignof(T) : AlignSize; alignas(align_size) char buffer[obj_size]; ///< Embedded memory buffer. }; diff --git a/include/srsran/adt/ring_buffer.h b/include/srsran/adt/ring_buffer.h index c821520080..99f3d8e27c 100644 --- a/include/srsran/adt/ring_buffer.h +++ b/include/srsran/adt/ring_buffer.h @@ -185,7 +185,7 @@ class ring_buffer_impl static_assert(std::is_same>::value or is_std_array::value, "Invalid container type. Only std::vector and std::array are supported"); - constexpr static bool has_static_size = is_std_array::value; + static constexpr bool has_static_size = is_std_array::value; using raw_container = typename detail::rebind_buffer_storage::type; using buffer_type = ring_buffer_storage; diff --git a/include/srsran/adt/slotted_array.h b/include/srsran/adt/slotted_array.h index 87824f6284..74bdcc15c3 100644 --- a/include/srsran/adt/slotted_array.h +++ b/include/srsran/adt/slotted_array.h @@ -356,7 +356,7 @@ class slotted_array template class slotted_vector { - constexpr static size_t absent_value = std::numeric_limits::max(); + static constexpr size_t absent_value = std::numeric_limits::max(); public: using value_type = T; diff --git a/include/srsran/asn1/asn1_utils.h b/include/srsran/asn1/asn1_utils.h index b377291401..8ea717b83a 100644 --- a/include/srsran/asn1/asn1_utils.h +++ b/include/srsran/asn1/asn1_utils.h @@ -1029,7 +1029,7 @@ class bitstring } private: - const static uint32_t stack_size = (UB == std::numeric_limits::max()) ? 4 : ceil_frac(ub, 8u); + static const uint32_t stack_size = (UB == std::numeric_limits::max()) ? 4 : ceil_frac(ub, 8u); ext_array octets_; uint32_t nof_bits = 0; }; diff --git a/include/srsran/du/du.h b/include/srsran/du/du.h index 357046d5ec..b965eb9426 100644 --- a/include/srsran/du/du.h +++ b/include/srsran/du/du.h @@ -11,7 +11,9 @@ #pragma once namespace srsran { +namespace srs_du { +/// Public DU interface. class du { public: @@ -24,4 +26,5 @@ class du virtual void stop() = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_cell_config.h b/include/srsran/du/du_cell_config.h index 7202ec5b05..f374d6fa4f 100644 --- a/include/srsran/du/du_cell_config.h +++ b/include/srsran/du/du_cell_config.h @@ -23,6 +23,7 @@ #include "srsran/scheduler/config/slice_rrm_policy_config.h" namespace srsran { +namespace srs_du { /// \brief Options for the number of Initial Cyclic Shifts that can be set for PUCCH Format 1. /// @@ -192,4 +193,5 @@ struct du_cell_config { std::vector rrm_policy_members; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_cell_config_helpers.h b/include/srsran/du/du_cell_config_helpers.h index 1922296b9b..229c832dc8 100644 --- a/include/srsran/du/du_cell_config_helpers.h +++ b/include/srsran/du/du_cell_config_helpers.h @@ -66,9 +66,9 @@ inline scheduler_expert_config make_default_scheduler_expert_config() } /// Generates default cell configuration used by gNB DU. The default configuration should be valid. -inline du_cell_config make_default_du_cell_config(const cell_config_builder_params_extended& params = {}) +inline srs_du::du_cell_config make_default_du_cell_config(const cell_config_builder_params_extended& params = {}) { - du_cell_config cfg{}; + srs_du::du_cell_config cfg{}; cfg.pci = params.pci; cfg.tac = 1; cfg.nr_cgi.plmn_id = plmn_identity::test_value(); diff --git a/include/srsran/du/du_cell_config_validation.h b/include/srsran/du/du_cell_config_validation.h index c2c7d92c4c..14b78027ef 100644 --- a/include/srsran/du/du_cell_config_validation.h +++ b/include/srsran/du/du_cell_config_validation.h @@ -14,6 +14,7 @@ #include "srsran/support/config/validator_result.h" namespace srsran { +namespace srs_du { /// \brief Checks whether the provided DU cell configuration is valid. /// @@ -21,4 +22,5 @@ namespace srsran { /// \return in case an invalid parameter is detected, returns a string containing an error message. validator_result is_du_cell_config_valid(const du_cell_config& cell_cfg); +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_high.h b/include/srsran/du/du_high/du_high.h index 7157e54569..00a22f9635 100644 --- a/include/srsran/du/du_high/du_high.h +++ b/include/srsran/du/du_high/du_high.h @@ -18,6 +18,7 @@ #include "srsran/ran/du_types.h" namespace srsran { +namespace srs_du { class du_configurator; @@ -51,4 +52,5 @@ class du_high virtual du_configurator& get_du_configurator() = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_high_configuration.h b/include/srsran/du/du_high/du_high_configuration.h index f08a00fd3b..b02250fbe2 100644 --- a/include/srsran/du/du_high/du_high_configuration.h +++ b/include/srsran/du/du_high/du_high_configuration.h @@ -42,20 +42,20 @@ struct du_high_ran_config { /// Configuration passed to DU-High. struct du_high_configuration { - du_high_ran_config ran; - du_high_executor_mapper* exec_mapper = nullptr; - f1c_connection_client* f1c_client = nullptr; - f1u_du_gateway* f1u_gw = nullptr; - mac_result_notifier* phy_adapter = nullptr; - timer_manager* timers = nullptr; - scheduler_metrics_notifier* sched_ue_metrics_notifier = nullptr; - rlc_metrics_notifier* rlc_metrics_notif = nullptr; - e2_connection_client* e2_client = nullptr; - e2_du_metrics_interface* e2_du_metric_iface = nullptr; - mac_pcap* mac_p = nullptr; - rlc_pcap* rlc_p = nullptr; - du_test_mode_config test_cfg; - e2ap_configuration e2ap_config; + srs_du::du_high_ran_config ran; + srs_du::du_high_executor_mapper* exec_mapper = nullptr; + f1c_connection_client* f1c_client = nullptr; + f1u_du_gateway* f1u_gw = nullptr; + mac_result_notifier* phy_adapter = nullptr; + timer_manager* timers = nullptr; + scheduler_metrics_notifier* sched_ue_metrics_notifier = nullptr; + rlc_metrics_notifier* rlc_metrics_notif = nullptr; + e2_connection_client* e2_client = nullptr; + e2_du_metrics_interface* e2_du_metric_iface = nullptr; + mac_pcap* mac_p = nullptr; + rlc_pcap* rlc_p = nullptr; + du_test_mode_config test_cfg; + e2ap_configuration e2ap_config; }; } // namespace srs_du diff --git a/include/srsran/du/du_high/du_high_executor_mapper.h b/include/srsran/du/du_high/du_high_executor_mapper.h index 2d6c078623..97f29c3817 100644 --- a/include/srsran/du/du_high/du_high_executor_mapper.h +++ b/include/srsran/du/du_high/du_high_executor_mapper.h @@ -14,6 +14,7 @@ #include "srsran/support/executors/task_executor.h" namespace srsran { +namespace srs_du { /// This interface is used to allow the DU to choose between different cell-specific task executors. class du_high_cell_executor_mapper @@ -85,4 +86,5 @@ class du_high_executor_mapper virtual task_executor& du_e2_executor() = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_high_factory.h b/include/srsran/du/du_high/du_high_factory.h index 9de4ffbdf1..067f1edf3e 100644 --- a/include/srsran/du/du_high/du_high_factory.h +++ b/include/srsran/du/du_high/du_high_factory.h @@ -14,8 +14,10 @@ #include "srsran/du/du_high/du_high_configuration.h" namespace srsran { +namespace srs_du { /// Create a DU-high instance, which comprises MAC, RLC and F1 layers. std::unique_ptr make_du_high(const srs_du::du_high_configuration& du_hi_cfg); +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_high_wrapper.h b/include/srsran/du/du_high/du_high_wrapper.h index 7dd05cec70..85b9750095 100644 --- a/include/srsran/du/du_high/du_high_wrapper.h +++ b/include/srsran/du/du_high/du_high_wrapper.h @@ -15,13 +15,13 @@ namespace srsran { namespace fapi { - class slot_data_message_notifier; class slot_error_message_notifier; class slot_time_message_notifier; - } // namespace fapi +namespace srs_du { + class du_high; /// Distributed Unit high wrapper interface. Wraps a DU high with the MAC FAPI adaptor. @@ -43,4 +43,5 @@ class du_high_wrapper : public du virtual fapi::slot_time_message_notifier& get_slot_time_message_notifier(unsigned cell_id) = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_high_wrapper_config.h b/include/srsran/du/du_high/du_high_wrapper_config.h index 8067f995af..f31a199b01 100644 --- a/include/srsran/du/du_high/du_high_wrapper_config.h +++ b/include/srsran/du/du_high/du_high_wrapper_config.h @@ -15,12 +15,12 @@ namespace srsran { namespace fapi { - class slot_message_gateway; class slot_last_message_notifier; - } // namespace fapi +namespace srs_du { + /// FAPI configuration for the DU high wrapper. struct du_high_wrapper_fapi_config { srslog::basic_levels log_level; @@ -47,4 +47,5 @@ struct du_high_wrapper_dependencies { std::vector sectors; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_high_wrapper_factory.h b/include/srsran/du/du_high/du_high_wrapper_factory.h index 41a2e4af93..d4fc154020 100644 --- a/include/srsran/du/du_high/du_high_wrapper_factory.h +++ b/include/srsran/du/du_high/du_high_wrapper_factory.h @@ -16,9 +16,11 @@ #include namespace srsran { +namespace srs_du { /// Creates a DU high wrapper with the given configuration and dependencies. std::unique_ptr make_du_high_wrapper(const du_high_wrapper_config& config, du_high_wrapper_dependencies&& dependencies); +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_manager/du_configurator.h b/include/srsran/du/du_high/du_manager/du_configurator.h index aed9fde3b5..10c416adbc 100644 --- a/include/srsran/du/du_high/du_manager/du_configurator.h +++ b/include/srsran/du/du_high/du_manager/du_configurator.h @@ -15,6 +15,7 @@ #include "srsran/support/async/async_task.h" namespace srsran { +namespace srs_du { struct control_config_params { // Sets the number of HARQ processes to be used. @@ -45,4 +46,5 @@ class du_configurator configure_ue_mac_scheduler(du_mac_sched_control_config reconf) = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_manager/du_manager_params.h b/include/srsran/du/du_high/du_manager/du_manager_params.h index 10e1a75be4..90248ddecf 100644 --- a/include/srsran/du/du_high/du_manager/du_manager_params.h +++ b/include/srsran/du/du_high/du_manager/du_manager_params.h @@ -39,19 +39,23 @@ struct du_manager_params { std::map srbs; std::map qos; }; + struct service_params { timer_manager& timers; task_executor& du_mng_exec; du_high_ue_executor_mapper& ue_execs; du_high_cell_executor_mapper& cell_execs; }; + struct f1ap_config_params { f1ap_connection_manager& conn_mng; f1ap_ue_context_manager& ue_mng; }; + struct f1u_config_params { f1u_du_gateway& f1u_gw; }; + struct rlc_config_params { mac_ue_control_information_handler& mac_ue_info_handler; f1ap_message_handler& f1ap_rx_msg_handler; @@ -59,6 +63,7 @@ struct du_manager_params { rlc_pcap& pcap_writer; rlc_metrics_notifier* rlc_metrics_notif = nullptr; }; + struct mac_config_params { mac_cell_manager& cell_mng; mac_ue_configurator& ue_cfg; diff --git a/include/srsran/du/du_high/du_qos_config.h b/include/srsran/du/du_high/du_qos_config.h index 3cbd293250..75406f2536 100644 --- a/include/srsran/du/du_high/du_qos_config.h +++ b/include/srsran/du/du_high/du_qos_config.h @@ -15,6 +15,7 @@ #include "srsran/rlc/rlc_config.h" namespace srsran { +namespace srs_du { /// \brief QoS Configuration, i.e. 5QI and the associated RLC configuration for DRBs struct du_qos_config { @@ -23,4 +24,5 @@ struct du_qos_config { mac_lc_config mac; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_high/du_qos_config_helpers.h b/include/srsran/du/du_high/du_qos_config_helpers.h index 0ed6257ec8..e64bd4dbaa 100644 --- a/include/srsran/du/du_high/du_qos_config_helpers.h +++ b/include/srsran/du/du_high/du_qos_config_helpers.h @@ -42,14 +42,15 @@ namespace config_helpers { /// Default value for RLC SDU queue limit in bytes are chosen such that it allows for 4096 PDCP pdus of 1500 of payload /// and 7 bytes of PDCP overhead. The SDU limit should be much larger then this, so that the limit is the number of /// bytes in the queue, not the number of SDUs, even in the case of small PDUs -const uint32_t default_rlc_queue_size_sdus = 16384; -const uint32_t default_rlc_queue_size_bytes = 4096 * (1500 + 7); -inline std::map make_default_du_qos_config_list(bool warn_on_drop, int rlc_metrics_report) +const uint32_t default_rlc_queue_size_sdus = 16384; +const uint32_t default_rlc_queue_size_bytes = 4096 * (1500 + 7); +inline std::map make_default_du_qos_config_list(bool warn_on_drop, + int rlc_metrics_report) { - std::map qos_list = {}; + std::map qos_list = {}; { // 5QI=1 - du_qos_config cfg{}; + srs_du::du_qos_config cfg{}; // RLC cfg.rlc.mode = rlc_mode::um_bidir; cfg.rlc.um.tx.sn_field_length = rlc_um_sn_size::size12bits; @@ -70,7 +71,7 @@ inline std::map make_default_du_qos_config_list(bool w } { // 5QI=2 - du_qos_config cfg{}; + srs_du::du_qos_config cfg{}; // RLC cfg.rlc.mode = rlc_mode::um_bidir; cfg.rlc.um.tx.sn_field_length = rlc_um_sn_size::size12bits; @@ -91,7 +92,7 @@ inline std::map make_default_du_qos_config_list(bool w } { // 5QI=5 - du_qos_config cfg{}; + srs_du::du_qos_config cfg{}; // RLC cfg.rlc.mode = rlc_mode::am; cfg.rlc.am.tx.sn_field_length = rlc_am_sn_size::size12bits; @@ -117,7 +118,7 @@ inline std::map make_default_du_qos_config_list(bool w } { // 5QI=7 - du_qos_config cfg{}; + srs_du::du_qos_config cfg{}; // RLC cfg.rlc.mode = rlc_mode::um_bidir; cfg.rlc.um.tx.sn_field_length = rlc_um_sn_size::size12bits; @@ -139,7 +140,7 @@ inline std::map make_default_du_qos_config_list(bool w } { // 5QI=9 - du_qos_config cfg{}; + srs_du::du_qos_config cfg{}; // RLC cfg.rlc.mode = rlc_mode::am; cfg.rlc.am.tx.sn_field_length = rlc_am_sn_size::size18bits; diff --git a/include/srsran/du/du_high/du_srb_config.h b/include/srsran/du/du_high/du_srb_config.h index 212df833ad..233a055715 100644 --- a/include/srsran/du/du_high/du_srb_config.h +++ b/include/srsran/du/du_high/du_srb_config.h @@ -14,6 +14,7 @@ #include "srsran/rlc/rlc_config.h" namespace srsran { +namespace srs_du { /// \brief SRB Configuration, i.e. associated RLC and MAC configuration for SRBs in the DU struct du_srb_config { @@ -21,4 +22,5 @@ struct du_srb_config { mac_lc_config mac; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_low/du_low.h b/include/srsran/du/du_low/du_low.h index 07d490f4e5..08211c4c1b 100644 --- a/include/srsran/du/du_low/du_low.h +++ b/include/srsran/du/du_low/du_low.h @@ -16,6 +16,8 @@ namespace srsran { class upper_phy; +namespace srs_du { + /// DU low interface. class du_low { @@ -33,4 +35,5 @@ class du_low virtual span get_all_upper_phys() = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_low/du_low_config.h b/include/srsran/du/du_low/du_low_config.h index aefb28adcc..4339724e33 100644 --- a/include/srsran/du/du_low/du_low_config.h +++ b/include/srsran/du/du_low/du_low_config.h @@ -13,6 +13,7 @@ #include "srsran/phy/upper/upper_phy_factories.h" namespace srsran { +namespace srs_du { /// DU low cell configuration struct du_low_cell_config { @@ -30,4 +31,5 @@ struct du_low_config { std::vector cells; }; -} // namespace srsran \ No newline at end of file +} // namespace srs_du +} // namespace srsran diff --git a/include/srsran/du/du_low/du_low_factory.h b/include/srsran/du/du_low/du_low_factory.h index 1af15dbbbd..014b2a4217 100644 --- a/include/srsran/du/du_low/du_low_factory.h +++ b/include/srsran/du/du_low/du_low_factory.h @@ -14,10 +14,12 @@ #include namespace srsran { +namespace srs_du { struct du_low_config; /// Creates and returns the DU low. std::unique_ptr make_du_low(const du_low_config& config); +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_low/du_low_wrapper.h b/include/srsran/du/du_low/du_low_wrapper.h index a22a689e9d..75392efdbe 100644 --- a/include/srsran/du/du_low/du_low_wrapper.h +++ b/include/srsran/du/du_low/du_low_wrapper.h @@ -20,6 +20,8 @@ class slot_message_gateway; class slot_time_message_notifier; } // namespace fapi +namespace srs_du { + class du_low; /// DU low wrapper interface. Wraps the DU low with the PHY-FAPI adatpor. @@ -51,4 +53,5 @@ class du_low_wrapper fapi::slot_data_message_notifier& fapi_data_notifier) = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_low/du_low_wrapper_config.h b/include/srsran/du/du_low/du_low_wrapper_config.h index 0f5c533ee3..425bf841ab 100644 --- a/include/srsran/du/du_low/du_low_wrapper_config.h +++ b/include/srsran/du/du_low/du_low_wrapper_config.h @@ -13,6 +13,7 @@ #include "srsran/du/du_low/du_low_config.h" namespace srsran { +namespace srs_du { struct du_cell_config; @@ -25,4 +26,5 @@ struct du_low_wrapper_config { std::vector prach_ports; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_low/du_low_wrapper_factory.h b/include/srsran/du/du_low/du_low_wrapper_factory.h index 1a4121c11f..22f5b00c7d 100644 --- a/include/srsran/du/du_low/du_low_wrapper_factory.h +++ b/include/srsran/du/du_low/du_low_wrapper_factory.h @@ -12,10 +12,10 @@ #include "srsran/adt/span.h" #include "srsran/du/du_low/du_low_wrapper.h" - #include namespace srsran { +namespace srs_du { struct du_cell_config; struct du_low_wrapper_config; @@ -24,4 +24,5 @@ struct du_low_wrapper_config; std::unique_ptr make_du_low_wrapper(const du_low_wrapper_config& config, span du_cells); +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_update_config_helpers.h b/include/srsran/du/du_update_config_helpers.h index b62e3df709..feb28a6150 100644 --- a/include/srsran/du/du_update_config_helpers.h +++ b/include/srsran/du/du_update_config_helpers.h @@ -24,7 +24,8 @@ namespace config_helpers { /// \param user_params parameters passed by the user for the generation the PUCCH resource list. /// \param bwp_size size of the BWP in RBs. /// \return PRACH frequency start. -unsigned compute_prach_frequency_start(const pucch_builder_params& user_params, unsigned bwp_size, bool is_long_prach); +unsigned +compute_prach_frequency_start(const srs_du::pucch_builder_params& user_params, unsigned bwp_size, bool is_long_prach); /// \brief Compute the number of PUCCH resources that are used for SR and CSI. /// @@ -34,12 +35,12 @@ unsigned compute_prach_frequency_start(const pucch_builder_params& user_params, /// \param max_pucch_grants_per_slot maximum number of PUCCH grants that can be allocated per slot in the cell. /// \param sr_period_msec SR period in milliseconds. /// \param csi_period_msec CSI period in milliseconds. -void compute_nof_sr_csi_pucch_res(pucch_builder_params& user_params, - unsigned max_pucch_grants_per_slot, - float sr_period_msec, - std::optional csi_period_msec); +void compute_nof_sr_csi_pucch_res(srs_du::pucch_builder_params& user_params, + unsigned max_pucch_grants_per_slot, + float sr_period_msec, + std::optional csi_period_msec); -bounded_integer compute_max_nof_pucch_symbols(const srs_builder_params& user_srs_params); +bounded_integer compute_max_nof_pucch_symbols(const srs_du::srs_builder_params& user_srs_params); } // namespace config_helpers } // namespace srsran diff --git a/include/srsran/du/du_wrapper.h b/include/srsran/du/du_wrapper.h index a0525ac91c..c49dc5c6a9 100644 --- a/include/srsran/du/du_wrapper.h +++ b/include/srsran/du/du_wrapper.h @@ -13,6 +13,7 @@ #include "srsran/du/du.h" namespace srsran { +namespace srs_du { class du_high_wrapper; class du_low_wrapper; @@ -30,4 +31,5 @@ class du_wrapper : public du virtual du_low_wrapper& get_du_low_wrapper() = 0; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_wrapper_config.h b/include/srsran/du/du_wrapper_config.h index ea3be4719d..3561dae43a 100644 --- a/include/srsran/du/du_wrapper_config.h +++ b/include/srsran/du/du_wrapper_config.h @@ -14,6 +14,7 @@ #include "srsran/du/du_low/du_low_wrapper_config.h" namespace srsran { +namespace srs_du { /// DU wrapper configuration. struct du_wrapper_config { @@ -21,4 +22,5 @@ struct du_wrapper_config { du_low_wrapper_config du_low_cfg; }; +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/du/du_wrapper_factory.h b/include/srsran/du/du_wrapper_factory.h index 006bc16515..6479832aa9 100644 --- a/include/srsran/du/du_wrapper_factory.h +++ b/include/srsran/du/du_wrapper_factory.h @@ -15,8 +15,10 @@ #include namespace srsran { +namespace srs_du { /// Instantiates a Distributed Unit (DU) wrapper object with the given configuration. std::unique_ptr make_du_wrapper(const du_wrapper_config& du_cfg); +} // namespace srs_du } // namespace srsran diff --git a/include/srsran/e1ap/common/e1ap_types.h b/include/srsran/e1ap/common/e1ap_types.h index 3542e24514..7becb3b5ff 100644 --- a/include/srsran/e1ap/common/e1ap_types.h +++ b/include/srsran/e1ap/common/e1ap_types.h @@ -27,7 +27,7 @@ namespace srsran { /// \brief GNB-CU-CP-UE-E1AP-ID used to identify the UE in the CU-CP E1AP. /// \remark See TS 38.463 Section 9.3.1.4: GNB-CU-UE-E1AP-ID valid values: (0..2^32-1) -constexpr static uint64_t MAX_NOF_CU_CP_E1AP_UES = ((uint64_t)1 << 32); +static constexpr uint64_t MAX_NOF_CU_CP_E1AP_UES = ((uint64_t)1 << 32); enum class gnb_cu_cp_ue_e1ap_id_t : uint64_t { min = 0, max = MAX_NOF_CU_CP_E1AP_UES - 1, invalid = 0x1ffffffff }; constexpr uint64_t gnb_cu_cp_ue_e1ap_id_to_uint(gnb_cu_cp_ue_e1ap_id_t id) @@ -43,7 +43,7 @@ constexpr gnb_cu_cp_ue_e1ap_id_t int_to_gnb_cu_cp_ue_e1ap_id(uint64_t idx) /// \brief GNB-CU-UP-UE-E1AP-ID used to identify the UE in the CU-UP E1AP. /// \remark See TS 38.473 Section 9.3.1.5: GNB-CU-UP-UE-E1AP-ID valid values: (0..2^32-1) -constexpr static uint64_t MAX_NOF_CU_UP_E1AP_UES = ((uint64_t)1 << 32); +static constexpr uint64_t MAX_NOF_CU_UP_E1AP_UES = ((uint64_t)1 << 32); enum class gnb_cu_up_ue_e1ap_id_t : uint64_t { min = 0, max = MAX_NOF_CU_CP_E1AP_UES - 1, invalid = 0x1ffffffff }; constexpr uint64_t gnb_cu_up_ue_e1ap_id_to_uint(gnb_cu_up_ue_e1ap_id_t id) diff --git a/include/srsran/e2/e2_event_manager.h b/include/srsran/e2/e2_event_manager.h index a02c6b306e..8ed4670fd3 100644 --- a/include/srsran/e2/e2_event_manager.h +++ b/include/srsran/e2/e2_event_manager.h @@ -25,7 +25,7 @@ class e2_event_manager { public: /// Transaction Response Container, which gets indexed by transaction_id. - constexpr static size_t MAX_NOF_TRANSACTIONS = 256; + static constexpr size_t MAX_NOF_TRANSACTIONS = 256; protocol_transaction_manager transactions; std::map, @@ -40,4 +40,4 @@ class e2_event_manager explicit e2_event_manager(timer_factory timers) : transactions(MAX_NOF_TRANSACTIONS, timers) {} }; -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/include/srsran/e2/e2_factory.h b/include/srsran/e2/e2_factory.h index 1c51ef9d27..aa3adf4a8e 100644 --- a/include/srsran/e2/e2_factory.h +++ b/include/srsran/e2/e2_factory.h @@ -44,7 +44,7 @@ std::unique_ptr create_e2_entity(e2ap_configuration& e2 e2_connection_client* e2_client_, e2_du_metrics_interface& e2_du_metrics_, srs_du::f1ap_ue_id_translator& f1ap_ue_id_translator_, - du_configurator& du_configurator_, + srs_du::du_configurator& du_configurator_, timer_factory timers_, task_executor& e2_exec_); diff --git a/include/srsran/f1ap/common/f1ap_ue_id.h b/include/srsran/f1ap/common/f1ap_ue_id.h index 4567933a30..c17a79df49 100644 --- a/include/srsran/f1ap/common/f1ap_ue_id.h +++ b/include/srsran/f1ap/common/f1ap_ue_id.h @@ -18,7 +18,7 @@ namespace srsran { /// \brief GNB-CU-UE-F1AP-ID used to identify the UE in the F1AP-CU. /// \remark See TS 38.473 Section 9.3.1.4: GNB-CU-UE-F1AP-ID valid values: (0..2^32-1) -constexpr static uint64_t MAX_NOF_CU_F1AP_UES = ((uint64_t)1 << 32); +static constexpr uint64_t MAX_NOF_CU_F1AP_UES = ((uint64_t)1 << 32); enum class gnb_cu_ue_f1ap_id_t : uint64_t { min = 0, max = MAX_NOF_CU_F1AP_UES - 1, invalid = 0x1ffffffff }; constexpr inline uint64_t gnb_cu_ue_f1ap_id_to_uint(gnb_cu_ue_f1ap_id_t id) @@ -34,7 +34,7 @@ constexpr inline gnb_cu_ue_f1ap_id_t int_to_gnb_cu_ue_f1ap_id(uint64_t idx) /// \brief GNB-DU-UE-F1AP-ID used to identify the UE in the F1AP-DU. /// \remark See TS 38.473 Section 9.3.1.5: GNB-DU-UE-F1AP-ID valid values: (0..2^32-1) -constexpr static uint64_t MAX_NOF_DU_F1AP_UES = (static_cast(1) << static_cast(32U)); +static constexpr uint64_t MAX_NOF_DU_F1AP_UES = (static_cast(1) << static_cast(32U)); enum class gnb_du_ue_f1ap_id_t : uint64_t { min = 0, max = MAX_NOF_DU_F1AP_UES - 1, invalid = 0x1ffffffff }; constexpr inline uint64_t gnb_du_ue_f1ap_id_to_uint(gnb_du_ue_f1ap_id_t id) diff --git a/include/srsran/f1ap/du/f1c_bearer.h b/include/srsran/f1ap/du/f1c_bearer.h index 7189cd5064..8186982831 100644 --- a/include/srsran/f1ap/du/f1c_bearer.h +++ b/include/srsran/f1ap/du/f1c_bearer.h @@ -14,8 +14,17 @@ #include "srsran/support/async/async_task.h" namespace srsran { + +class task_executor; + namespace srs_du { +class f1ap_du; +class du_high_ue_executor_mapper; +class f1ap_du_configurator; +class f1ap_du_paging_notifier; +class f1c_connection_client; + /// \brief This interface represents the data entry point of the transmitting side of a F1-C bearer of the DU. /// The lower layer will use this class to pass F1AP SDUs (e.g. PDCP PDUs/RLC SDUs) into the F1-C bearer towards CU-CP. class f1c_tx_sdu_handler @@ -68,5 +77,10 @@ class f1c_rx_pdu_handler class f1c_bearer : public f1c_tx_sdu_handler, public f1c_tx_delivery_handler, public f1c_rx_pdu_handler {}; +std::unique_ptr create_f1ap(f1c_connection_client& f1c_client_handler, + f1ap_du_configurator& du_mng, + task_executor& ctrl_exec, + du_high_ue_executor_mapper& ue_exec_mapper, + f1ap_du_paging_notifier& paging_notifier); } // namespace srs_du } // namespace srsran diff --git a/include/srsran/mac/config/mac_cell_group_config_factory.h b/include/srsran/mac/config/mac_cell_group_config_factory.h index 83c0c7d20e..a1273cc183 100644 --- a/include/srsran/mac/config/mac_cell_group_config_factory.h +++ b/include/srsran/mac/config/mac_cell_group_config_factory.h @@ -16,7 +16,7 @@ namespace srsran { namespace config_helpers { -mac_cell_group_config make_initial_mac_cell_group_config(const mac_cell_group_params& mcg_params = {}); +mac_cell_group_config make_initial_mac_cell_group_config(const srs_du::mac_cell_group_params& mcg_params = {}); } // namespace config_helpers } // namespace srsran diff --git a/include/srsran/mac/config/mac_config_helpers.h b/include/srsran/mac/config/mac_config_helpers.h index a24fa8ee45..721ab3620d 100644 --- a/include/srsran/mac/config/mac_config_helpers.h +++ b/include/srsran/mac/config/mac_config_helpers.h @@ -15,11 +15,13 @@ namespace srsran { +namespace srs_du { struct du_cell_config; +} /// Derives MAC Cell Configuration from DU Cell Configuration. mac_cell_creation_request make_mac_cell_config(du_cell_index_t cell_index, - const du_cell_config& du_cfg, + const srs_du::du_cell_config& du_cfg, std::vector bcch_dl_sch_payloads, const sched_cell_configuration_request_message& sched_cell_cfg); diff --git a/include/srsran/mac/mac_config.h b/include/srsran/mac/mac_config.h index 81e3ac678b..ee1c230d3b 100644 --- a/include/srsran/mac/mac_config.h +++ b/include/srsran/mac/mac_config.h @@ -38,13 +38,13 @@ struct mac_expert_config { /// \brief Configuration passed to MAC during its instantiation. struct mac_config { - mac_ul_ccch_notifier& ul_ccch_notifier; - du_high_ue_executor_mapper& ue_exec_mapper; - du_high_cell_executor_mapper& cell_exec_mapper; - task_executor& ctrl_exec; - mac_result_notifier& phy_notifier; - mac_expert_config mac_cfg; - mac_pcap& pcap; + mac_ul_ccch_notifier& ul_ccch_notifier; + srs_du::du_high_ue_executor_mapper& ue_exec_mapper; + srs_du::du_high_cell_executor_mapper& cell_exec_mapper; + task_executor& ctrl_exec; + mac_result_notifier& phy_notifier; + mac_expert_config mac_cfg; + mac_pcap& pcap; // Parameters passed to MAC scheduler. scheduler_expert_config sched_cfg; scheduler_metrics_notifier& metric_notifier; diff --git a/include/srsran/ngap/ngap_types.h b/include/srsran/ngap/ngap_types.h index 15467648b2..1b76cf5b94 100644 --- a/include/srsran/ngap/ngap_types.h +++ b/include/srsran/ngap/ngap_types.h @@ -19,7 +19,7 @@ namespace srs_cu_cp { /// \brief AMF_UE_ID (non ASN1 type of AMF_UE_NGAP_ID) used to identify the UE in the AMF. /// \remark See TS 38.413 Section 9.3.3.1: AMF_UE_NGAP_ID valid values: (0..2^40-1) -constexpr static uint64_t MAX_NOF_AMF_UES = ((uint64_t)1 << 40); +static constexpr uint64_t MAX_NOF_AMF_UES = ((uint64_t)1 << 40); enum class amf_ue_id_t : uint64_t { min = 0, max = MAX_NOF_AMF_UES - 1, invalid = 0x1ffffffffff }; /// Convert AMF_UE_ID type to integer. @@ -48,4 +48,4 @@ struct ngap_ue_aggr_max_bit_rate { }; } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/include/srsran/nru/nru_packing.h b/include/srsran/nru/nru_packing.h index 0d65a6da6f..b7a4b61796 100644 --- a/include/srsran/nru/nru_packing.h +++ b/include/srsran/nru/nru_packing.h @@ -74,7 +74,7 @@ struct formatter { template auto format(srsran::nru_pdu_type pdu_type, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"dl_user_data", "dl_data_delivery_status", "assistance_information"}; + static constexpr const char* options[] = {"dl_user_data", "dl_data_delivery_status", "assistance_information"}; if (nru_pdu_type_to_uint(pdu_type) < nru_pdu_type_to_uint(srsran::nru_pdu_type::reserved)) { format_to(ctx.out(), "{}", options[nru_pdu_type_to_uint(pdu_type)]); } diff --git a/include/srsran/ofh/ethernet/ethernet_unique_buffer.h b/include/srsran/ofh/ethernet/ethernet_unique_buffer.h index c7f9c5c589..ebdefc7df3 100644 --- a/include/srsran/ofh/ethernet/ethernet_unique_buffer.h +++ b/include/srsran/ofh/ethernet/ethernet_unique_buffer.h @@ -89,7 +89,7 @@ class unique_rx_buffer static_assert(sizeof(rx_buffer_wrapper) <= storage_capacity.value(), "Pre-allocated storage does not have enough space to store passed rx buffer"); - const static detail::storage_helper_impl helper{}; + static const detail::storage_helper_impl helper{}; storage_ptr = &helper; ::new (&buffer) T(std::forward(rx_buffer_wrapper)); } diff --git a/include/srsran/pdcp/pdcp_config.h b/include/srsran/pdcp/pdcp_config.h index 412de3c41f..9ff61925ad 100644 --- a/include/srsran/pdcp/pdcp_config.h +++ b/include/srsran/pdcp/pdcp_config.h @@ -267,7 +267,7 @@ struct formatter { template auto format(srsran::pdcp_rb_type type, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"SRB", "DRB"}; + static constexpr const char* options[] = {"SRB", "DRB"}; return format_to(ctx.out(), "{}", options[static_cast(type)]); } }; @@ -284,7 +284,7 @@ struct formatter { template auto format(srsran::pdcp_rlc_mode mode, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"UM", "AM"}; + static constexpr const char* options[] = {"UM", "AM"}; return format_to(ctx.out(), "{}", options[static_cast(mode)]); } }; diff --git a/include/srsran/psup/psup_message.h b/include/srsran/psup/psup_message.h index ddd3bb71e2..30538e47a3 100644 --- a/include/srsran/psup/psup_message.h +++ b/include/srsran/psup/psup_message.h @@ -34,7 +34,7 @@ constexpr inline psup_pdu_type uint_to_psup_pdu_type(uint8_t num) } // See TS 38.415 Sec. 5.5.3.7: Pagin Policy Indicator (PPI) - value range: (0..7) -constexpr static uint8_t MAX_NOF_PPI = 8; +static constexpr uint8_t MAX_NOF_PPI = 8; /// PSUP Paging Policy Indicator (PPI) /// diff --git a/include/srsran/ran/csi_rs/csi_meas_config.h b/include/srsran/ran/csi_rs/csi_meas_config.h index 57b69db7c5..8c29610d69 100644 --- a/include/srsran/ran/csi_rs/csi_meas_config.h +++ b/include/srsran/ran/csi_rs/csi_meas_config.h @@ -83,7 +83,7 @@ inline unsigned csi_resource_periodicity_to_uint(csi_resource_periodicity val) inline const span csi_resource_periodicity_options() { - const static std::array list{csi_resource_periodicity::slots4, + static const std::array list{csi_resource_periodicity::slots4, csi_resource_periodicity::slots5, csi_resource_periodicity::slots8, csi_resource_periodicity::slots10, diff --git a/include/srsran/ran/cu_types.h b/include/srsran/ran/cu_types.h index 8194c4116d..33f6a8f221 100644 --- a/include/srsran/ran/cu_types.h +++ b/include/srsran/ran/cu_types.h @@ -23,7 +23,7 @@ namespace srsran { // See TS 38.463 Section 9.3.1.21: PDU Session ID valid values: (0..255) -constexpr static uint16_t MAX_NOF_PDU_SESSIONS = 256; +static constexpr uint16_t MAX_NOF_PDU_SESSIONS = 256; /// \brief PDU Session ID. /// \remark See TS 38.463 Section 9.3.1.21: PDU Session ID valid values: (0..255) @@ -43,7 +43,7 @@ constexpr inline pdu_session_id_t uint_to_pdu_session_id(uint16_t idx) /// \brief RAN_UE_ID (non ASN1 type of RAN_UE_NGAP_ID). /// \remark See TS 38.413 Section 9.3.3.2: RAN_UE_NGAP_ID valid values: (0..2^32-1) -constexpr static uint64_t MAX_NOF_RAN_UES = ((uint64_t)1 << 32); +static constexpr uint64_t MAX_NOF_RAN_UES = ((uint64_t)1 << 32); enum class ran_ue_id_t : uint64_t { min = 0, max = MAX_NOF_RAN_UES - 1, invalid = 0x1ffffffff }; /// Convert RAN_UE_ID type to integer. diff --git a/include/srsran/ran/duplex_mode.h b/include/srsran/ran/duplex_mode.h index 1b32358e1b..a86b59f51a 100644 --- a/include/srsran/ran/duplex_mode.h +++ b/include/srsran/ran/duplex_mode.h @@ -29,7 +29,7 @@ enum class duplex_mode { inline const char* to_string(duplex_mode mode) { - constexpr static const char* names[] = {"FDD", "TDD", "SDL", "SUL", "invalid"}; + static constexpr const char* names[] = {"FDD", "TDD", "SDL", "SUL", "invalid"}; return names[std::min((unsigned)mode, (unsigned)duplex_mode::INVALID)]; } diff --git a/include/srsran/ran/frequency_range.h b/include/srsran/ran/frequency_range.h index 6ca21e2470..ddf156103c 100644 --- a/include/srsran/ran/frequency_range.h +++ b/include/srsran/ran/frequency_range.h @@ -24,7 +24,7 @@ enum class frequency_range { inline const char* to_string(frequency_range freq_range) { - constexpr static const char* names[] = {"FR1", "FR2", "invalid"}; + static constexpr const char* names[] = {"FR1", "FR2", "invalid"}; return names[std::min(static_cast(freq_range), static_cast(frequency_range::FR2) + 1U)]; } diff --git a/include/srsran/ran/lcid.h b/include/srsran/ran/lcid.h index cff5034fc5..1c240f8057 100644 --- a/include/srsran/ran/lcid.h +++ b/include/srsran/ran/lcid.h @@ -74,7 +74,7 @@ inline lcid_t srb_id_to_lcid(srb_id_t srb_id) inline const char* srb_id_to_string(srb_id_t srb_id) { - constexpr static const char* names[] = {"SRB0", "SRB1", "SRB2", "SRB3", "invalid"}; + static constexpr const char* names[] = {"SRB0", "SRB1", "SRB2", "SRB3", "invalid"}; return names[srb_id_to_uint(srb_id < srb_id_t::nulltype ? srb_id : srb_id_t::nulltype)]; } @@ -111,7 +111,7 @@ enum class drb_id_t : uint8_t { invalid }; -constexpr static std::size_t MAX_NOF_DRBS = 29; +static constexpr std::size_t MAX_NOF_DRBS = 29; constexpr inline uint8_t drb_id_to_uint(drb_id_t id) { diff --git a/include/srsran/ran/pci.h b/include/srsran/ran/pci.h index 0583c420e1..4a9357d1d7 100644 --- a/include/srsran/ran/pci.h +++ b/include/srsran/ran/pci.h @@ -14,10 +14,17 @@ namespace srsran { -/// 3GPP TS 38.331, PhysCellId ::= INTEGER (0..1007) +/// 3GPP TS 38.331, PhysCellId ::= INTEGER (0..1007). using pci_t = uint16_t; constexpr pci_t MIN_PCI = 0; constexpr pci_t MAX_PCI = 1007; constexpr pci_t INVALID_PCI = MAX_PCI + 1; +/// Returns true if the given struct is valid, otherwise false. +constexpr bool is_valid(pci_t pci) +{ + // PCI must be in [0..1007]. + return pci < INVALID_PCI; +} + } // namespace srsran diff --git a/include/srsran/ran/pci_helpers.h b/include/srsran/ran/pci_helpers.h deleted file mode 100644 index 916c958851..0000000000 --- a/include/srsran/ran/pci_helpers.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * Copyright 2021-2024 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#pragma once - -#include "pci.h" - -namespace srsran { -namespace config_helpers { - -/// Returns true if the given struct is valid, otherwise false. -inline bool is_valid(const pci_t pci) -{ - // PCI must be in [0..1007] - if (pci >= INVALID_PCI) { - fmt::print("Invalid pci={}.\n", pci); - return false; - } - - return true; -} - -} // namespace config_helpers -} // namespace srsran diff --git a/include/srsran/ran/pdcch/pdcch_candidates.h b/include/srsran/ran/pdcch/pdcch_candidates.h index 8808541ca3..3c0fe03f6e 100644 --- a/include/srsran/ran/pdcch/pdcch_candidates.h +++ b/include/srsran/ran/pdcch/pdcch_candidates.h @@ -29,7 +29,7 @@ using pdcch_candidate_list = static_vector max_monitored_pdcch_candidates_per_slot = {44, 36, 22, 20}; + static const std::array max_monitored_pdcch_candidates_per_slot = {44, 36, 22, 20}; return max_monitored_pdcch_candidates_per_slot[to_numerology_value(scs)]; } diff --git a/include/srsran/ran/qos/five_qi.h b/include/srsran/ran/qos/five_qi.h index 334c001ee3..6378526534 100644 --- a/include/srsran/ran/qos/five_qi.h +++ b/include/srsran/ran/qos/five_qi.h @@ -16,7 +16,7 @@ namespace srsran { // See TS 38.463: Five QI valid values: (0..255) -constexpr static uint16_t MAX_FIVEQI = 255; +static constexpr uint16_t MAX_FIVEQI = 255; /// \brief Five QI. enum class five_qi_t : uint16_t { min = 0, max = MAX_FIVEQI, invalid = MAX_FIVEQI + 1 }; diff --git a/include/srsran/ran/qos/qos_flow_id.h b/include/srsran/ran/qos/qos_flow_id.h index 532d21110a..3a7145c42e 100644 --- a/include/srsran/ran/qos/qos_flow_id.h +++ b/include/srsran/ran/qos/qos_flow_id.h @@ -16,7 +16,7 @@ namespace srsran { // See TS 38.463 Section 9.3.1.24: QoS Flow ID valid values: (0..63) -constexpr static uint8_t MAX_NOF_QOS_FLOWS = 64; +static constexpr uint8_t MAX_NOF_QOS_FLOWS = 64; /// \brief QoS Flow ID. /// \remark See TS 38.463 Section 9.3.1.21: QoS Flow ID valid values: (0..63) @@ -58,4 +58,4 @@ struct formatter { } }; -} // namespace fmt \ No newline at end of file +} // namespace fmt diff --git a/include/srsran/ran/qos/qos_prio_level.h b/include/srsran/ran/qos/qos_prio_level.h index 6d11066a63..2ddb7e4bf8 100644 --- a/include/srsran/ran/qos/qos_prio_level.h +++ b/include/srsran/ran/qos/qos_prio_level.h @@ -16,7 +16,7 @@ namespace srsran { // See TS 38.473: QoS Priority Level valid values: (0..127) -constexpr static uint8_t MAX_QOS_PRIO_LEVEL = 127; +static constexpr uint8_t MAX_QOS_PRIO_LEVEL = 127; /// \brief QoS Priority Level. enum class qos_prio_level_t : uint8_t { min = 0, max = MAX_QOS_PRIO_LEVEL, invalid = MAX_QOS_PRIO_LEVEL + 1 }; diff --git a/include/srsran/rlc/rlc_config.h b/include/srsran/rlc/rlc_config.h index e3cc985bcd..eb7cc17da2 100644 --- a/include/srsran/rlc/rlc_config.h +++ b/include/srsran/rlc/rlc_config.h @@ -783,7 +783,7 @@ struct formatter { template auto format(srsran::rlc_dc_field dc, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"ctrl", "data"}; + static constexpr const char* options[] = {"ctrl", "data"}; return format_to(ctx.out(), "{}", options[to_number(dc)]); } }; @@ -799,7 +799,7 @@ struct formatter { template auto format(srsran::rlc_si_field si, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"full", "first", "last", "mid"}; + static constexpr const char* options[] = {"full", "first", "last", "mid"}; return format_to(ctx.out(), "{}", options[to_number(si)]); } }; diff --git a/include/srsran/rlc/rlc_mode.h b/include/srsran/rlc/rlc_mode.h index d93c6c7fe5..dd6daaed0c 100644 --- a/include/srsran/rlc/rlc_mode.h +++ b/include/srsran/rlc/rlc_mode.h @@ -58,9 +58,9 @@ struct formatter { template auto format(srsran::rlc_mode mode, FormatContext& ctx) { - constexpr static const char* options[] = {"TM", "UM Bi-dir", "UM Uni-dir-UL", "UM Uni-dir-DL", "AM"}; + static constexpr const char* options[] = {"TM", "UM Bi-dir", "UM Uni-dir-UL", "UM Uni-dir-DL", "AM"}; return format_to(ctx.out(), "{}", options[static_cast(mode)]); } }; -} // namespace fmt \ No newline at end of file +} // namespace fmt diff --git a/include/srsran/rlc/rlc_tx_metrics.h b/include/srsran/rlc/rlc_tx_metrics.h index 4b4dde9d44..b74ee8411c 100644 --- a/include/srsran/rlc/rlc_tx_metrics.h +++ b/include/srsran/rlc/rlc_tx_metrics.h @@ -90,7 +90,7 @@ struct rlc_tx_metrics_lower { // Histogram of pull pdus static constexpr unsigned pdu_latency_hist_bins = 8; - constexpr static unsigned nof_usec_per_bin = 10; + static constexpr unsigned nof_usec_per_bin = 10; std::array pdu_latency_hist_ns; uint32_t max_pdu_latency_ns; diff --git a/include/srsran/scheduler/config/sched_cell_config_helpers.h b/include/srsran/scheduler/config/sched_cell_config_helpers.h index bacc5ae60b..f3a78e1ee4 100644 --- a/include/srsran/scheduler/config/sched_cell_config_helpers.h +++ b/include/srsran/scheduler/config/sched_cell_config_helpers.h @@ -17,7 +17,8 @@ namespace srsran { namespace config_helpers { /// Builds the list of PUCCH guardbands. -std::vector build_pucch_guardbands_list(const pucch_builder_params& ul_cfg, unsigned bwp_size); +std::vector build_pucch_guardbands_list(const srs_du::pucch_builder_params& ul_cfg, + unsigned bwp_size); } // namespace config_helpers } // namespace srsran diff --git a/include/srsran/scheduler/scheduler_metrics.h b/include/srsran/scheduler/scheduler_metrics.h index 11290e7ac9..3789a139d3 100644 --- a/include/srsran/scheduler/scheduler_metrics.h +++ b/include/srsran/scheduler/scheduler_metrics.h @@ -51,9 +51,9 @@ struct scheduler_ue_metrics { /// \brief Snapshot of the metrics for a cell and its UEs. struct scheduler_cell_metrics { /// Latency histogram number of bins. - constexpr static unsigned latency_hist_bins = 10; + static constexpr unsigned latency_hist_bins = 10; /// Distance between histogram bins. - constexpr static unsigned nof_usec_per_bin = 50; + static constexpr unsigned nof_usec_per_bin = 50; /// Number of cell PRBs. unsigned nof_prbs = 0; diff --git a/include/srsran/sdap/sdap_config.h b/include/srsran/sdap/sdap_config.h index d85789f16f..57f05de703 100644 --- a/include/srsran/sdap/sdap_config.h +++ b/include/srsran/sdap/sdap_config.h @@ -49,7 +49,7 @@ struct formatter { template auto format(srsran::sdap_hdr_ul_cfg hdr_cfg, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"present", "absent"}; + static constexpr const char* options[] = {"present", "absent"}; return format_to(ctx.out(), "{}", options[static_cast(hdr_cfg)]); } }; @@ -66,7 +66,7 @@ struct formatter { template auto format(srsran::sdap_hdr_dl_cfg hdr_cfg, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"present", "absent"}; + static constexpr const char* options[] = {"present", "absent"}; return format_to(ctx.out(), "{}", options[static_cast(hdr_cfg)]); } }; diff --git a/include/srsran/security/security.h b/include/srsran/security/security.h index f9ace67f96..9296369428 100644 --- a/include/srsran/security/security.h +++ b/include/srsran/security/security.h @@ -301,7 +301,7 @@ struct formatter { auto format(srsran::security::security_direction dir, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"UL", "DL"}; + static constexpr const char* options[] = {"UL", "DL"}; return format_to(ctx.out(), "{}", options[static_cast(dir)]); } }; @@ -319,7 +319,7 @@ struct formatter { auto format(srsran::security::integrity_enabled integrity_flag, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"off", "on"}; + static constexpr const char* options[] = {"off", "on"}; return format_to(ctx.out(), "{}", options[static_cast(integrity_flag)]); } }; @@ -337,7 +337,7 @@ struct formatter { auto format(srsran::security::ciphering_enabled ciphering_flag, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"off", "on"}; + static constexpr const char* options[] = {"off", "on"}; return format_to(ctx.out(), "{}", options[static_cast(ciphering_flag)]); } }; @@ -405,7 +405,7 @@ struct formatter { template auto format(srsran::security::sec_domain domain, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"RRC", "UP"}; + static constexpr const char* options[] = {"RRC", "UP"}; return format_to(ctx.out(), "{}", options[static_cast(domain)]); } }; diff --git a/include/srsran/security/ssl.h b/include/srsran/security/ssl.h index bbaabb3380..3855cfcb62 100644 --- a/include/srsran/security/ssl.h +++ b/include/srsran/security/ssl.h @@ -22,7 +22,7 @@ using aes_context = mbedtls_aes_context; constexpr int aes_encrypt = 1; constexpr int aes_decrypt = 0; -inline int aes_setkey_enc(aes_context* ctx, const unsigned char* key, unsigned int keysize) +inline int aes_setkey_enc(aes_context* ctx, const unsigned char* key, unsigned keysize) { return mbedtls_aes_setkey_enc(ctx, key, keysize); } diff --git a/include/srsran/security/zuc.h b/include/srsran/security/zuc.h index 7bf644fd9d..d68b636e4d 100644 --- a/include/srsran/security/zuc.h +++ b/include/srsran/security/zuc.h @@ -14,7 +14,7 @@ namespace srsran { namespace security { typedef unsigned char u8; -typedef unsigned int u32; +typedef unsigned u32; /* the state registers of LFSR */ typedef struct { diff --git a/lib/asn1/asn1_utils.cpp b/lib/asn1/asn1_utils.cpp index 9db8508246..318bc155ca 100644 --- a/lib/asn1/asn1_utils.cpp +++ b/lib/asn1/asn1_utils.cpp @@ -1538,7 +1538,7 @@ json_writer::json_writer() : ident(""), sep(NONE) {} void json_writer::write_fieldname(const char* fieldname) { - constexpr static const char* septable[] = {",\n", "\n", ""}; + static constexpr const char* septable[] = {",\n", "\n", ""}; fmt::format_to(buffer, "{}{}", septable[sep], sep != NONE ? ident : ""); if (strlen(fieldname) != 0) { diff --git a/lib/du/du_cell_config_validation.cpp b/lib/du/du_cell_config_validation.cpp index 4cd9bdf446..3aa1ae8ae6 100644 --- a/lib/du/du_cell_config_validation.cpp +++ b/lib/du/du_cell_config_validation.cpp @@ -22,6 +22,7 @@ #include using namespace srsran; +using namespace srs_du; #define CHECK_TRUE(cond, ...) \ if (not(cond)) { \ @@ -695,7 +696,7 @@ static check_outcome check_tdd_ul_dl_config(const du_cell_config& cell_cfg) return {}; } -check_outcome srsran::is_du_cell_config_valid(const du_cell_config& cell_cfg) +check_outcome srs_du::is_du_cell_config_valid(const du_cell_config& cell_cfg) { CHECK_EQ_OR_BELOW(cell_cfg.pci, MAX_PCI, "cell PCI"); CHECK_EQ_OR_BELOW(cell_cfg.scs_common, subcarrier_spacing::kHz120, "SCS common"); diff --git a/lib/du/du_high/adapters/du_high_adapter_factories.h b/lib/du/du_high/adapters/du_high_adapter_factories.h index 9d086079a7..6a42ac4d25 100644 --- a/lib/du/du_high/adapters/du_high_adapter_factories.h +++ b/lib/du/du_high/adapters/du_high_adapter_factories.h @@ -15,9 +15,11 @@ #include "srsran/mac/mac_config.h" namespace srsran { +namespace srs_du { /// \brief Create a MAC instance for DU-high. In case the test mode is enabled, the MAC messages will be intercepted. std::unique_ptr create_du_high_mac(const mac_config& mac_cfg, const srs_du::du_test_mode_config& test_cfg); +} // namespace srs_du } // namespace srsran diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp index 9fb580b17b..9c8aa87a4f 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp @@ -18,6 +18,7 @@ #include using namespace srsran; +using namespace srs_du; // Buffer state that the fake RLC will report to the MAC. This value should be large enough for the scheduler to fill // the largest TB possible. @@ -679,8 +680,8 @@ void mac_test_mode_adapter::handle_ue_config_applied(du_ue_index_t ue_idx) mac_adapted->get_ue_configurator().handle_ue_config_applied(ue_idx); } -std::unique_ptr srsran::create_du_high_mac(const mac_config& mac_cfg, - const srs_du::du_test_mode_config& test_cfg) +std::unique_ptr srsran::srs_du::create_du_high_mac(const mac_config& mac_cfg, + const srs_du::du_test_mode_config& test_cfg) { if (not test_cfg.test_ue.has_value()) { return create_mac(mac_cfg); diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.h b/lib/du/du_high/adapters/mac_test_mode_adapter.h index 60f8be14a1..63a54b3bb2 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.h +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.h @@ -17,6 +17,7 @@ #include namespace srsran { +namespace srs_du { class phy_test_mode_adapter : public mac_result_notifier { @@ -246,4 +247,5 @@ class mac_test_mode_adapter final : public mac_interface, test_ue_info_manager ue_info_mgr; }; +} // namespace srs_du } // namespace srsran diff --git a/lib/du/du_high/du_high_executor_strategies.h b/lib/du/du_high/du_high_executor_strategies.h index c70f8f589b..1749eebdfa 100644 --- a/lib/du/du_high/du_high_executor_strategies.h +++ b/lib/du/du_high/du_high_executor_strategies.h @@ -14,6 +14,7 @@ #include "srsran/support/srsran_assert.h" namespace srsran { +namespace srs_du { /// L2 UL executor mapper that maps UEs based on their RNTI. class index_based_ue_executor_mapper final : public du_high_ue_executor_mapper @@ -216,4 +217,5 @@ class du_high_executor_mapper_impl final : public du_high_executor_mapper task_executor* du_e2_exec; }; +} // namespace srs_du } // namespace srsran diff --git a/lib/du/du_high/du_high_factory.cpp b/lib/du/du_high/du_high_factory.cpp index 19b69ed4b1..6ae21bf7c5 100644 --- a/lib/du/du_high/du_high_factory.cpp +++ b/lib/du/du_high/du_high_factory.cpp @@ -12,8 +12,9 @@ #include "du_high_impl.h" using namespace srsran; +using namespace srs_du; -std::unique_ptr srsran::make_du_high(const srs_du::du_high_configuration& du_hi_cfg) +std::unique_ptr srsran::srs_du::make_du_high(const srs_du::du_high_configuration& du_hi_cfg) { return std::make_unique(du_hi_cfg); } diff --git a/lib/du/du_high/du_high_wrapper_factory.cpp b/lib/du/du_high/du_high_wrapper_factory.cpp index b5cdb1a1fa..1107c0908d 100644 --- a/lib/du/du_high/du_high_wrapper_factory.cpp +++ b/lib/du/du_high/du_high_wrapper_factory.cpp @@ -19,6 +19,7 @@ #include "srsran/fapi_adaptor/uci_part2_correspondence_generator.h" using namespace srsran; +using namespace srs_du; static std::unique_ptr build_mac_fapi_adaptor(unsigned sector_id, @@ -223,8 +224,9 @@ class mac_fapi_adaptor_with_logger_and_message_buffering_impl : public fapi_adap } // namespace -std::unique_ptr srsran::make_du_high_wrapper(const du_high_wrapper_config& config, - du_high_wrapper_dependencies&& wrapper_dependencies) +std::unique_ptr +srsran::srs_du::make_du_high_wrapper(const du_high_wrapper_config& config, + du_high_wrapper_dependencies&& wrapper_dependencies) { srsran_assert(config.du_hi.ran.cells.size() == wrapper_dependencies.sectors.size(), "DU high number of cells '{}' does not match number sectors '{}' in wrapper dependencies", diff --git a/lib/du/du_high/du_high_wrapper_impl.cpp b/lib/du/du_high/du_high_wrapper_impl.cpp index 70e2f91f46..a29a2d08bc 100644 --- a/lib/du/du_high/du_high_wrapper_impl.cpp +++ b/lib/du/du_high/du_high_wrapper_impl.cpp @@ -11,6 +11,7 @@ #include "du_high_wrapper_impl.h" using namespace srsran; +using namespace srs_du; namespace { /// Dummy implementation of the mac_result_notifier. diff --git a/lib/du/du_high/du_high_wrapper_impl.h b/lib/du/du_high/du_high_wrapper_impl.h index d4951a203e..d8cdf3f2a9 100644 --- a/lib/du/du_high/du_high_wrapper_impl.h +++ b/lib/du/du_high/du_high_wrapper_impl.h @@ -16,6 +16,7 @@ #include "srsran/fapi_adaptor/mac/mac_fapi_adaptor.h" namespace srsran { +namespace srs_du { /// DU high wrapper implementation dependencies. struct du_high_wrapper_impl_dependencies { @@ -60,4 +61,5 @@ class du_high_wrapper_impl : public du_high_wrapper std::unique_ptr du_hi; }; +} // namespace srs_du } // namespace srsran diff --git a/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp b/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp index 267e3e7e43..e3de1c11da 100644 --- a/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp +++ b/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp @@ -368,13 +368,13 @@ asn1::rrc_nr::bwp_dl_common_s srsran::srs_du::make_asn1_init_dl_bwp(const dl_con pdcch.coreset_zero_present = false; pdcch.common_coreset_present = cfg.init_dl_bwp.pdcch_common.common_coreset.has_value(); if (pdcch.common_coreset_present) { - pdcch.common_coreset = srsran::srs_du::make_asn1_rrc_coreset(cfg.init_dl_bwp.pdcch_common.common_coreset.value()); + pdcch.common_coreset = make_asn1_rrc_coreset(cfg.init_dl_bwp.pdcch_common.common_coreset.value()); } // Sent by MIB. pdcch.search_space_zero_present = false; for (size_t ss_idx = 1; ss_idx < cfg.init_dl_bwp.pdcch_common.search_spaces.size(); ++ss_idx) { const search_space_configuration& ss = cfg.init_dl_bwp.pdcch_common.search_spaces[ss_idx]; - pdcch.common_search_space_list.push_back(srsran::srs_du::make_asn1_rrc_search_space(ss)); + pdcch.common_search_space_list.push_back(make_asn1_rrc_search_space(ss)); } pdcch.search_space_sib1_present = true; pdcch.search_space_sib1 = cfg.init_dl_bwp.pdcch_common.sib1_search_space_id; diff --git a/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.cpp b/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.cpp index f98f67bacb..93b7b171ce 100644 --- a/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.cpp +++ b/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.cpp @@ -16,6 +16,7 @@ #include "srsran/support/error_handling.h" using namespace srsran; +using namespace srs_du; byte_buffer srsran::srs_du::make_asn1_rrc_cell_mib_buffer(const du_cell_config& du_cfg) { diff --git a/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h b/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h index 53277dc049..3d7bfe5e3b 100644 --- a/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h +++ b/lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h @@ -16,7 +16,6 @@ #include "srsran/ran/ntn.h" namespace srsran { - namespace srs_du { /// \brief Derive packed cell MIB from DU cell configuration. @@ -51,5 +50,4 @@ void fill_f1_setup_request(f1_setup_request_message& req, std::vector* sib1_jsons = nullptr); } // namespace srs_du - } // namespace srsran diff --git a/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.cpp b/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.cpp index 0d593c1c61..8b2e847f00 100644 --- a/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.cpp +++ b/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.cpp @@ -19,9 +19,9 @@ using namespace srs_du; /// Derives Scheduler Cell Configuration from DU Cell Configuration. sched_cell_configuration_request_message -srsran::srs_du::make_sched_cell_config_req(du_cell_index_t cell_index, - const du_cell_config& du_cfg, - span si_payload_sizes) +srsran::srs_du::make_sched_cell_config_req(du_cell_index_t cell_index, + const srs_du::du_cell_config& du_cfg, + span si_payload_sizes) { srsran_assert(si_payload_sizes.size() >= 1, "SIB1 payload size needs to be set"); srsran_assert(si_payload_sizes.size() - 1 == diff --git a/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h b/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h index 3f71645621..29d4f6c194 100644 --- a/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h +++ b/lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h @@ -14,20 +14,18 @@ #include "srsran/scheduler/scheduler_configurator.h" namespace srsran { - -struct du_cell_config; - namespace srs_du { +struct du_cell_config; struct du_ue_context; struct du_ue_resource_config; /// Derives Scheduler Cell Configuration from DU Cell Configuration. -sched_cell_configuration_request_message make_sched_cell_config_req(du_cell_index_t cell_index, - const du_cell_config& du_cfg, - span si_payload_sizes); +sched_cell_configuration_request_message make_sched_cell_config_req(du_cell_index_t cell_index, + const srs_du::du_cell_config& du_cfg, + span si_payload_sizes); -// Create scheduler UE Configuration Request based on DU UE configuration context. +/// Create scheduler UE Configuration Request based on DU UE configuration context. sched_ue_config_request create_scheduler_ue_config_request(const du_ue_context& ue_ctx, const du_ue_resource_config& ue_res_cfg); diff --git a/lib/du/du_high/du_manager/du_manager_impl.h b/lib/du/du_high/du_manager/du_manager_impl.h index 13f12e8079..0c618fb25c 100644 --- a/lib/du/du_high/du_manager/du_manager_impl.h +++ b/lib/du/du_high/du_manager/du_manager_impl.h @@ -61,7 +61,7 @@ class du_manager_impl final : public du_manager_interface size_t nof_ues() override; async_task - configure_ue_mac_scheduler(srsran::du_mac_sched_control_config reconf) override; + configure_ue_mac_scheduler(du_mac_sched_control_config reconf) override; private: // DU manager configuration that will be visible to all running procedures diff --git a/lib/du/du_high/du_manager/du_ue/du_bearer.cpp b/lib/du/du_high/du_manager/du_ue/du_bearer.cpp index f8ee1540dd..58f8b60ad7 100644 --- a/lib/du/du_high/du_manager/du_ue/du_bearer.cpp +++ b/lib/du/du_high/du_manager/du_ue/du_bearer.cpp @@ -161,13 +161,13 @@ std::unique_ptr srsran::srs_du::create_drb(const drb_creation_info& d } // > Create F1-U bearer. - srsran::srs_du::f1u_bearer_creation_message f1u_msg = {}; - f1u_msg.ue_index = ue_index; - f1u_msg.drb_id = drb->drb_id; - f1u_msg.config = drb_info.f1u_cfg; - f1u_msg.dl_tnl_info = drb->dluptnl_info_list[0]; - f1u_msg.rx_sdu_notifier = &drb->connector.f1u_rx_sdu_notif; - f1u_msg.tx_pdu_notifier = drb->f1u_gw_bearer.get(); + f1u_bearer_creation_message f1u_msg = {}; + f1u_msg.ue_index = ue_index; + f1u_msg.drb_id = drb->drb_id; + f1u_msg.config = drb_info.f1u_cfg; + f1u_msg.dl_tnl_info = drb->dluptnl_info_list[0]; + f1u_msg.rx_sdu_notifier = &drb->connector.f1u_rx_sdu_notif; + f1u_msg.tx_pdu_notifier = drb->f1u_gw_bearer.get(); f1u_msg.timers = timer_factory{drb_info.du_params.services.timers, drb_info.du_params.services.ue_execs.ctrl_executor(ue_index)}; f1u_msg.ue_executor = &drb_info.du_params.services.ue_execs.f1u_dl_pdu_executor(ue_index); diff --git a/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp index 8203d93a21..7016b871d2 100644 --- a/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp +++ b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp @@ -19,11 +19,11 @@ namespace { const char* get_rlf_cause_str(rlf_cause cause) { switch (cause) { - case srsran::srs_du::rlf_cause::max_mac_kos_reached: + case rlf_cause::max_mac_kos_reached: return "MAC max KOs reached"; - case srsran::srs_du::rlf_cause::max_rlc_retxs_reached: + case rlf_cause::max_rlc_retxs_reached: return "RLC max ReTxs reached"; - case srsran::srs_du::rlf_cause::rlc_protocol_failure: + case rlf_cause::rlc_protocol_failure: return "RLC protocol failure"; default: break; diff --git a/lib/du/du_high/du_manager/procedures/procedure_logger.h b/lib/du/du_high/du_manager/procedures/procedure_logger.h index 858bb3ca15..31095b5a5e 100644 --- a/lib/du/du_high/du_manager/procedures/procedure_logger.h +++ b/lib/du/du_high/du_manager/procedures/procedure_logger.h @@ -16,6 +16,7 @@ #include "srsran/support/format_utils.h" namespace srsran { +namespace srs_du { class du_procedure_logger { @@ -104,4 +105,5 @@ class ue_procedure_logger rnti_t rnti; }; -} // namespace srsran \ No newline at end of file +} // namespace srs_du +} // namespace srsran diff --git a/lib/du/du_high/du_manager/procedures/ue_configuration_procedure.cpp b/lib/du/du_high/du_manager/procedures/ue_configuration_procedure.cpp index bb5111d78b..17097993c6 100644 --- a/lib/du/du_high/du_manager/procedures/ue_configuration_procedure.cpp +++ b/lib/du/du_high/du_manager/procedures/ue_configuration_procedure.cpp @@ -16,7 +16,7 @@ #include "srsran/scheduler/config/logical_channel_config_factory.h" using namespace srsran; -using namespace srsran::srs_du; +using namespace srs_du; ue_configuration_procedure::ue_configuration_procedure(const f1ap_ue_context_update_request& request_, du_ue_manager_repository& ue_mng_, diff --git a/lib/du/du_high/du_manager/procedures/ue_creation_procedure.cpp b/lib/du/du_high/du_manager/procedures/ue_creation_procedure.cpp index 13a39b5c40..8cd8b9fbf8 100644 --- a/lib/du/du_high/du_manager/procedures/ue_creation_procedure.cpp +++ b/lib/du/du_high/du_manager/procedures/ue_creation_procedure.cpp @@ -16,7 +16,7 @@ #include "srsran/rlc/rlc_srb_config_factory.h" using namespace srsran; -using namespace srsran::srs_du; +using namespace srs_du; ue_creation_procedure::ue_creation_procedure(const du_ue_creation_request& req_, du_ue_manager_repository& ue_mng_, diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp index 94d3e40a6f..56134f64bb 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp @@ -142,7 +142,7 @@ du_pucch_resource_manager::find_optimal_csi_report_slot_offset( // [Implementation-defined] Given that it takes some time for a UE to process a CSI-RS and integrate its estimate // in the following CSI report, we consider a minimum slot distance before which CSI report slot offsets should be // avoided. - constexpr static unsigned MINIMUM_CSI_RS_REPORT_DISTANCE = 4; + static constexpr unsigned MINIMUM_CSI_RS_REPORT_DISTANCE = 4; // TODO: Support more than one nzp-CSI-RS resource for measurement. const csi_res_config_id_t csi_res_cfg_id = csi_meas_cfg.csi_report_cfg_list[0].res_for_channel_meas; @@ -308,7 +308,7 @@ bool du_pucch_resource_manager::alloc_resources(cell_group_config& cell_grp_cfg) // Update the PUCCH max payload. // As per TS 38.231, Section 9.2.1, with PUCCH Format 1, we can have up to 2 HARQ-ACK bits (SR doesn't count as part // of the payload). - constexpr static unsigned pucch_f1_max_harq_payload = 2U; + static constexpr unsigned pucch_f1_max_harq_payload = 2U; cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.pucch_cfg.value().format_max_payload[pucch_format_to_uint( pucch_format::FORMAT_1)] = pucch_f1_max_harq_payload; cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.pucch_cfg.value().format_max_payload[pucch_format_to_uint( @@ -456,7 +456,7 @@ unsigned du_pucch_resource_manager::pucch_res_idx_to_csi_du_res_idx(unsigned puc user_defined_pucch_cfg.nof_cell_harq_pucch_res_sets); } -void du_pucch_resource_manager::disable_pucch_cfg(srsran::srs_du::cell_group_config& cell_grp_cfg) +void du_pucch_resource_manager::disable_pucch_cfg(cell_group_config& cell_grp_cfg) { auto& serv_cell = cell_grp_cfg.cells[0].serv_cell_cfg; diff --git a/lib/du/du_low/du_low_factory.cpp b/lib/du/du_low/du_low_factory.cpp index 32da1e489d..639693608f 100644 --- a/lib/du/du_low/du_low_factory.cpp +++ b/lib/du/du_low/du_low_factory.cpp @@ -14,12 +14,13 @@ #include "srsran/support/error_handling.h" using namespace srsran; +using namespace srs_du; static std::unique_ptr create_upper_phy(const upper_phy_config& upper_config, const downlink_processor_factory_sw_config& dl_fact_config) { // Create downlink processor factory. - std::shared_ptr dl_proc_factory = nullptr; + std::shared_ptr dl_proc_factory; // Check if a hardware-accelerated PDSCH processor is requested. if (!upper_config.hal_config.hwacc_pdsch_processor) { dl_proc_factory = create_downlink_processor_factory_sw(dl_fact_config); @@ -50,7 +51,7 @@ static std::unique_ptr create_upper_phy(const upper_phy_config& return upper_phy_factory->create(upper_config); } -std::unique_ptr srsran::make_du_low(const du_low_config& config) +std::unique_ptr srsran::srs_du::make_du_low(const du_low_config& config) { std::vector> upper; for (const auto& cell_cfg : config.cells) { diff --git a/lib/du/du_low/du_low_impl.cpp b/lib/du/du_low/du_low_impl.cpp index 22d3286564..ea9e5c0335 100644 --- a/lib/du/du_low/du_low_impl.cpp +++ b/lib/du/du_low/du_low_impl.cpp @@ -11,12 +11,14 @@ #include "du_low_impl.h" using namespace srsran; +using namespace srs_du; du_low_impl::du_low_impl(std::vector> upper_) : upper(std::move(upper_)) { srsran_assert(!upper.empty(), "Invalid upper PHY"); - for (auto& up : upper) + for (auto& up : upper) { upper_ptrs.push_back(up.get()); + } } upper_phy& du_low_impl::get_upper_phy(unsigned cell_id) diff --git a/lib/du/du_low/du_low_impl.h b/lib/du/du_low/du_low_impl.h index 0a732e4acc..5526467efc 100644 --- a/lib/du/du_low/du_low_impl.h +++ b/lib/du/du_low/du_low_impl.h @@ -14,6 +14,7 @@ #include "srsran/phy/upper/upper_phy.h" namespace srsran { +namespace srs_du { /// DU low implementation. class du_low_impl final : public du_low @@ -35,4 +36,5 @@ class du_low_impl final : public du_low std::vector upper_ptrs; }; +} // namespace srs_du } // namespace srsran diff --git a/lib/du/du_low/du_low_wrapper_factory.cpp b/lib/du/du_low/du_low_wrapper_factory.cpp index 1898293525..499caa09fc 100644 --- a/lib/du/du_low/du_low_wrapper_factory.cpp +++ b/lib/du/du_low/du_low_wrapper_factory.cpp @@ -19,6 +19,7 @@ #include "srsran/fapi_adaptor/uci_part2_correspondence_generator.h" using namespace srsran; +using namespace srs_du; static fapi::prach_config generate_prach_config_tlv(const du_cell_config& cell_cfg) { @@ -114,8 +115,8 @@ static std::unique_ptr create_phy_fapi_adaptor(u return adaptor_factory->create(phy_fapi_config, std::move(phy_fapi_dependencies)); } -std::unique_ptr srsran::make_du_low_wrapper(const du_low_wrapper_config& config, - span du_cells) +std::unique_ptr srsran::srs_du::make_du_low_wrapper(const du_low_wrapper_config& config, + span du_cells) { srsran_assert(config.du_low_cfg.cells.size() == du_cells.size(), "Number of cells mismatch between upper PHY '{}' and DU high '{}'", diff --git a/lib/du/du_low/du_low_wrapper_impl.cpp b/lib/du/du_low/du_low_wrapper_impl.cpp index 137c32974c..a585303936 100644 --- a/lib/du/du_low/du_low_wrapper_impl.cpp +++ b/lib/du/du_low/du_low_wrapper_impl.cpp @@ -13,6 +13,7 @@ #include "srsran/support/srsran_assert.h" using namespace srsran; +using namespace srs_du; du_low_wrapper_impl::du_low_wrapper_impl(std::unique_ptr du_lo_, std::vector> fapi_adaptors_) : diff --git a/lib/du/du_low/du_low_wrapper_impl.h b/lib/du/du_low/du_low_wrapper_impl.h index 009869f6ba..e8ae58a50c 100644 --- a/lib/du/du_low/du_low_wrapper_impl.h +++ b/lib/du/du_low/du_low_wrapper_impl.h @@ -17,6 +17,7 @@ #include namespace srsran { +namespace srs_du { class du_low_wrapper_impl final : public du_low_wrapper { @@ -48,4 +49,5 @@ class du_low_wrapper_impl final : public du_low_wrapper std::vector> fapi_adaptors; }; +} // namespace srs_du } // namespace srsran diff --git a/lib/du/du_update_config_helpers.cpp b/lib/du/du_update_config_helpers.cpp index f1d34dbdff..2a75c11754 100644 --- a/lib/du/du_update_config_helpers.cpp +++ b/lib/du/du_update_config_helpers.cpp @@ -12,6 +12,7 @@ #include "du_high/du_manager/ran_resource_management/pucch_resource_generator.h" using namespace srsran; +using namespace config_helpers; /// Helper that computes the greatest RB index used by the PUCCH resources on the BWP's left side. Note that the PUCCH /// resources are located at in 2 separate blocks, at both sides of the BWP, i.e., 1 block on the left side (where @@ -59,9 +60,9 @@ static unsigned greatest_used_rb_on_bwp_left_side(const pucch_resource& res, uns return max_rb_idx_on_left_side; } -unsigned srsran::config_helpers::compute_prach_frequency_start(const pucch_builder_params& user_params, - unsigned bwp_size, - bool is_long_prach) +unsigned srsran::config_helpers::compute_prach_frequency_start(const srs_du::pucch_builder_params& user_params, + unsigned bwp_size, + bool is_long_prach) { // This is to preserve a guardband between the PUCCH and PRACH. const unsigned pucch_to_prach_guardband = is_long_prach ? 0U : 3U; @@ -88,10 +89,10 @@ unsigned srsran::config_helpers::compute_prach_frequency_start(const pucch_build return prach_f_start + pucch_to_prach_guardband; } -void srsran::config_helpers::compute_nof_sr_csi_pucch_res(pucch_builder_params& user_params, - unsigned max_pucch_grants_per_slot, - float sr_period_msec, - std::optional csi_period_msec) +void srsran::config_helpers::compute_nof_sr_csi_pucch_res(srs_du::pucch_builder_params& user_params, + unsigned max_pucch_grants_per_slot, + float sr_period_msec, + std::optional csi_period_msec) { // [Implementation-defined] In the following, we compute the estimated number of PUCCH resources that are needed for // SR and CSI; we assume we cannot allocate more than max_pucch_grants_per_slot - 1U (1 is reserved for HARQ-ACK) @@ -120,7 +121,7 @@ void srsran::config_helpers::compute_nof_sr_csi_pucch_res(pucch_builder_params& } bounded_integer -srsran::config_helpers::compute_max_nof_pucch_symbols(const srs_builder_params& user_srs_params) +srsran::config_helpers::compute_max_nof_pucch_symbols(const srs_du::srs_builder_params& user_srs_params) { // [Implementation-defined] In the following, we compute the maximum number of PUCCH symbols that can be used in a // slot based on the PUCCH and SRS configurations. The maximum number of PUCCH symbols is computed so that PUCCH and diff --git a/lib/du/du_wrapper_factory.cpp b/lib/du/du_wrapper_factory.cpp index 2be897b4aa..4832f016e5 100644 --- a/lib/du/du_wrapper_factory.cpp +++ b/lib/du/du_wrapper_factory.cpp @@ -14,8 +14,9 @@ #include "srsran/du/du_low/du_low_wrapper_factory.h" using namespace srsran; +using namespace srs_du; -std::unique_ptr srsran::make_du_wrapper(const du_wrapper_config& du_cfg) +std::unique_ptr srsran::srs_du::make_du_wrapper(const du_wrapper_config& du_cfg) { du_wrapper_impl_dependencies dependencies; diff --git a/lib/du/du_wrapper_impl.cpp b/lib/du/du_wrapper_impl.cpp index 410cabf2d1..0fef8f927e 100644 --- a/lib/du/du_wrapper_impl.cpp +++ b/lib/du/du_wrapper_impl.cpp @@ -14,6 +14,7 @@ #include "srsran/support/srsran_assert.h" using namespace srsran; +using namespace srs_du; du_wrapper_impl::du_wrapper_impl(du_wrapper_impl_dependencies&& dependencies) : du_lo(std::move(dependencies.du_lo)), du_hi(std::move(dependencies.du_hi)) diff --git a/lib/du/du_wrapper_impl.h b/lib/du/du_wrapper_impl.h index df1be2a1e9..8a6a5af4a6 100644 --- a/lib/du/du_wrapper_impl.h +++ b/lib/du/du_wrapper_impl.h @@ -17,6 +17,7 @@ #include namespace srsran { +namespace srs_du { /// DU wrapper implementation dependencies. struct du_wrapper_impl_dependencies { @@ -47,4 +48,5 @@ class du_wrapper_impl final : public du_wrapper std::unique_ptr du_hi; }; +} // namespace srs_du } // namespace srsran diff --git a/lib/e1ap/cu_cp/procedures/e1ap_transaction_manager.h b/lib/e1ap/cu_cp/procedures/e1ap_transaction_manager.h index 6c8e2c423d..eafd1c388e 100644 --- a/lib/e1ap/cu_cp/procedures/e1ap_transaction_manager.h +++ b/lib/e1ap/cu_cp/procedures/e1ap_transaction_manager.h @@ -26,11 +26,11 @@ class e1ap_transaction_manager { public: /// Transaction Response Container, which gets indexed by transaction_id. - constexpr static size_t MAX_NOF_TRANSACTIONS = 256; + static constexpr size_t MAX_NOF_TRANSACTIONS = 256; protocol_transaction_manager transactions; explicit e1ap_transaction_manager(timer_factory timers) : transactions(MAX_NOF_TRANSACTIONS, timers) {} }; } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/e1ap/cu_up/procedures/e1ap_cu_up_event_manager.h b/lib/e1ap/cu_up/procedures/e1ap_cu_up_event_manager.h index 4bb36042b4..8b6128b7c7 100644 --- a/lib/e1ap/cu_up/procedures/e1ap_cu_up_event_manager.h +++ b/lib/e1ap/cu_up/procedures/e1ap_cu_up_event_manager.h @@ -27,7 +27,7 @@ using e1ap_transaction = protocol_transaction; class e1ap_event_manager { /// Transaction Response Container, which gets indexed by transaction_id. - constexpr static size_t MAX_NOF_TRANSACTIONS = 256; + static constexpr size_t MAX_NOF_TRANSACTIONS = 256; public: protocol_transaction_manager transactions; diff --git a/lib/e2/common/e2_entity.cpp b/lib/e2/common/e2_entity.cpp index 7ab46c2aa1..1c7360491d 100644 --- a/lib/e2/common/e2_entity.cpp +++ b/lib/e2/common/e2_entity.cpp @@ -37,7 +37,7 @@ e2_entity::e2_entity(e2ap_configuration& cfg_, e2_connection_client* e2_client_, e2_du_metrics_interface& e2_du_metrics_iface_, srs_du::f1ap_ue_id_translator& f1ap_ue_id_translator_, - du_configurator& du_configurator_, + srs_du::du_configurator& du_configurator_, timer_factory timers_, task_executor& task_exec_) : logger(srslog::fetch_basic_logger("E2")), cfg(cfg_), task_exec(task_exec_), main_ctrl_loop(128) diff --git a/lib/e2/common/e2_entity.h b/lib/e2/common/e2_entity.h index cb561ea915..085ab57352 100644 --- a/lib/e2/common/e2_entity.h +++ b/lib/e2/common/e2_entity.h @@ -38,7 +38,7 @@ class e2_entity final : public e2_interface e2_connection_client* e2_client_, e2_du_metrics_interface& e2_du_metrics_, srs_du::f1ap_ue_id_translator& f1ap_ue_id_translator_, - du_configurator& du_configurator_, + srs_du::du_configurator& du_configurator_, timer_factory timers_, task_executor& task_exec_); diff --git a/lib/e2/common/e2_factory.cpp b/lib/e2/common/e2_factory.cpp index 8452cbadc7..f6f8783979 100644 --- a/lib/e2/common/e2_factory.cpp +++ b/lib/e2/common/e2_factory.cpp @@ -41,7 +41,7 @@ std::unique_ptr srsran::create_e2_entity(e2ap_configuration& e2_connection_client* e2_client_, e2_du_metrics_interface& e2_du_metrics_, srs_du::f1ap_ue_id_translator& f1ap_ue_id_translator_, - du_configurator& du_configurator_, + srs_du::du_configurator& du_configurator_, timer_factory timers_, task_executor& e2_exec_) { diff --git a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp index 3cba612897..a43685e824 100644 --- a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp +++ b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.cpp @@ -15,8 +15,9 @@ using namespace asn1::e2ap; using namespace asn1::e2sm; using namespace srsran; -e2sm_rc_control_action_du_executor_base::e2sm_rc_control_action_du_executor_base(du_configurator& du_configurator_, - uint32_t action_id_) : +e2sm_rc_control_action_du_executor_base::e2sm_rc_control_action_du_executor_base( + srs_du::du_configurator& du_configurator_, + uint32_t action_id_) : logger(srslog::fetch_basic_logger("E2SM-RC")), action_id(action_id_), du_param_configurator(du_configurator_) { } @@ -56,7 +57,7 @@ e2sm_rc_control_action_du_executor_base::return_ctrl_failure(const e2sm_ric_cont void e2sm_rc_control_action_du_executor_base::parse_ran_parameter_value(const ran_param_value_type_c& ran_param, uint64_t ran_param_id, uint64_t ue_id, - du_mac_sched_control_config& ctrl_cfg) + srs_du::du_mac_sched_control_config& ctrl_cfg) { if (ran_param.type() == ran_param_value_type_c::types_opts::ran_p_choice_list) { for (auto& ran_p_list : ran_param.ran_p_choice_list().ran_param_list.list_of_ran_param) { @@ -77,7 +78,8 @@ void e2sm_rc_control_action_du_executor_base::parse_ran_parameter_value(const ra } } -e2sm_rc_control_action_2_6_du_executor::e2sm_rc_control_action_2_6_du_executor(du_configurator& du_configurator_) : +e2sm_rc_control_action_2_6_du_executor::e2sm_rc_control_action_2_6_du_executor( + srs_du::du_configurator& du_configurator_) : e2sm_rc_control_action_du_executor_base(du_configurator_, 6) { // Control Action description: @@ -97,13 +99,14 @@ e2sm_rc_control_action_2_6_du_executor::e2sm_rc_control_action_2_6_du_executor(d action_params.insert({13, "Dedicated PRB Policy Ratio"}); }; -void e2sm_rc_control_action_2_6_du_executor::parse_action_ran_parameter_value(const ran_param_value_type_c& ran_param, - uint64_t ran_param_id, - uint64_t ue_id, - du_mac_sched_control_config& ctrl_cfg) +void e2sm_rc_control_action_2_6_du_executor::parse_action_ran_parameter_value( + const ran_param_value_type_c& ran_param, + uint64_t ran_param_id, + uint64_t ue_id, + srs_du::du_mac_sched_control_config& ctrl_cfg) { if (action_params[ran_param_id] == "PLMN Identity") { - control_config_params cur_control_params = {}; + srs_du::control_config_params cur_control_params = {}; cur_control_params.rrm_policy_group.emplace(); cur_control_params.rrm_policy_group.value().pol_member.plmn_id = plmn_identity::parse(ran_param.ran_p_choice_elem_false().ran_param_value.value_oct_s().to_string()).value(); @@ -111,7 +114,7 @@ void e2sm_rc_control_action_2_6_du_executor::parse_action_ran_parameter_value(co } else if (action_params[ran_param_id] == "SST") { if (ctrl_cfg.param_list.size()) { if (ctrl_cfg.param_list.back().rrm_policy_group.value().pol_member.s_nssai.sst) { - control_config_params cur_control_params = {}; + srs_du::control_config_params cur_control_params = {}; cur_control_params.rrm_policy_group.emplace(); cur_control_params = ctrl_cfg.param_list.back(); cur_control_params.rrm_policy_group.value().pol_member.s_nssai.sst = @@ -125,7 +128,7 @@ void e2sm_rc_control_action_2_6_du_executor::parse_action_ran_parameter_value(co } else if (action_params[ran_param_id] == "SD") { if (ctrl_cfg.param_list.size()) { if (ctrl_cfg.param_list.back().rrm_policy_group.value().pol_member.s_nssai.sd.has_value()) { - control_config_params cur_control_params = {}; + srs_du::control_config_params cur_control_params = {}; cur_control_params.rrm_policy_group.emplace(); cur_control_params = ctrl_cfg.param_list.back(); cur_control_params.rrm_policy_group.value().pol_member.s_nssai.sd.emplace(); @@ -147,7 +150,7 @@ void e2sm_rc_control_action_2_6_du_executor::parse_action_ran_parameter_value(co ctrl_cfg.param_list.back().rrm_policy_group.value().min_prb_policy_ratio = ran_param.ran_p_choice_elem_false().ran_param_value.value_int(); } else { - control_config_params cur_control_params = {}; + srs_du::control_config_params cur_control_params = {}; cur_control_params.rrm_policy_group.emplace(); cur_control_params.rrm_policy_group.value().min_prb_policy_ratio.emplace(); cur_control_params.rrm_policy_group.value().min_prb_policy_ratio = @@ -163,7 +166,7 @@ void e2sm_rc_control_action_2_6_du_executor::parse_action_ran_parameter_value(co ctrl_cfg.param_list.back().rrm_policy_group.value().max_prb_policy_ratio = ran_param.ran_p_choice_elem_false().ran_param_value.value_int(); } else { - control_config_params cur_control_params = {}; + srs_du::control_config_params cur_control_params = {}; cur_control_params.rrm_policy_group.emplace(); cur_control_params.rrm_policy_group.value().max_prb_policy_ratio.emplace(); cur_control_params.rrm_policy_group.value().max_prb_policy_ratio = @@ -192,25 +195,25 @@ bool e2sm_rc_control_action_2_6_du_executor::ric_control_action_supported(const async_task e2sm_rc_control_action_2_6_du_executor::execute_ric_control_action(const e2sm_ric_control_request& req) { - du_mac_sched_control_config ctrl_config = convert_to_du_config_request(req); + srs_du::du_mac_sched_control_config ctrl_config = convert_to_du_config_request(req); if (ctrl_config.param_list.empty()) { return return_ctrl_failure(req); } return launch_async( [this, ctrl_config = std::move(ctrl_config)](coro_context>& ctx) { CORO_BEGIN(ctx); - du_mac_sched_control_config_response ctrl_response; + srs_du::du_mac_sched_control_config_response ctrl_response; CORO_AWAIT_VALUE(ctrl_response, du_param_configurator.configure_ue_mac_scheduler(ctrl_config)); e2sm_ric_control_response e2_resp = convert_to_e2sm_response(ctrl_config, ctrl_response); CORO_RETURN(e2_resp); }); }; -du_mac_sched_control_config +srs_du::du_mac_sched_control_config e2sm_rc_control_action_2_6_du_executor::convert_to_du_config_request(const e2sm_ric_control_request& e2sm_req_) { - du_mac_sched_control_config ctrl_config = {}; - const e2sm_rc_ctrl_hdr_format1_s& ctrl_hdr = + srs_du::du_mac_sched_control_config ctrl_config = {}; + const e2sm_rc_ctrl_hdr_format1_s& ctrl_hdr = std::get(e2sm_req_.request_ctrl_hdr).ric_ctrl_hdr_formats.ctrl_hdr_format1(); const e2sm_rc_ctrl_msg_format1_s& ctrl_msg = std::get(e2sm_req_.request_ctrl_msg).ric_ctrl_msg_formats.ctrl_msg_format1(); @@ -238,8 +241,8 @@ e2sm_rc_control_action_2_6_du_executor::convert_to_du_config_request(const e2sm_ } e2sm_ric_control_response e2sm_rc_control_action_2_6_du_executor::convert_to_e2sm_response( - const du_mac_sched_control_config& du_config_req_, - const du_mac_sched_control_config_response& du_response_) + const srs_du::du_mac_sched_control_config& du_config_req_, + const srs_du::du_mac_sched_control_config_response& du_response_) { e2sm_ric_control_response e2sm_response; e2sm_response.success = @@ -251,7 +254,7 @@ e2sm_ric_control_response e2sm_rc_control_action_2_6_du_executor::convert_to_e2s .ric_ctrl_outcome_formats.set_ctrl_outcome_format1(); // TODO: fill outcome properly - control_config_params req = du_config_req_.param_list[0]; + srs_du::control_config_params req = du_config_req_.param_list[0]; if (req.rrm_policy_group.has_value()) { e2sm_rc_ctrl_outcome_format1_item_s min_prb_outcome; min_prb_outcome.ran_param_id = 10; diff --git a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h index 177751b659..c52879dde4 100644 --- a/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h +++ b/lib/e2/e2sm/e2sm_rc/e2sm_rc_control_action_du_executor.h @@ -23,7 +23,7 @@ class e2sm_rc_control_action_du_executor_base : public e2sm_control_action_execu { public: e2sm_rc_control_action_du_executor_base() = delete; - e2sm_rc_control_action_du_executor_base(du_configurator& du_configurator_, uint32_t action_id_); + e2sm_rc_control_action_du_executor_base(srs_du::du_configurator& du_configurator_, uint32_t action_id_); virtual ~e2sm_rc_control_action_du_executor_base() = default; bool fill_ran_function_description(asn1::e2sm::ran_function_definition_ctrl_action_item_s& action_item); @@ -35,11 +35,11 @@ class e2sm_rc_control_action_du_executor_base : public e2sm_control_action_execu virtual void parse_action_ran_parameter_value(const asn1::e2sm::ran_param_value_type_c& ran_p, uint64_t ran_param_id, uint64_t ue_id, - du_mac_sched_control_config& ctrl_cfg) = 0; + srs_du::du_mac_sched_control_config& ctrl_cfg) = 0; void parse_ran_parameter_value(const asn1::e2sm::ran_param_value_type_c& ran_p, uint64_t ran_param_id, uint64_t ue_id, - du_mac_sched_control_config& ctrl_cfg); + srs_du::du_mac_sched_control_config& ctrl_cfg); async_task return_ctrl_failure(const e2sm_ric_control_request& req); protected: @@ -47,13 +47,13 @@ class e2sm_rc_control_action_du_executor_base : public e2sm_control_action_execu uint32_t action_id; std::string action_name; std::map action_params; - du_configurator& du_param_configurator; + srs_du::du_configurator& du_param_configurator; }; class e2sm_rc_control_action_2_6_du_executor : public e2sm_rc_control_action_du_executor_base { public: - e2sm_rc_control_action_2_6_du_executor(du_configurator& du_configurator_); + e2sm_rc_control_action_2_6_du_executor(srs_du::du_configurator& du_configurator_); virtual ~e2sm_rc_control_action_2_6_du_executor() = default; /// e2sm_control_request_executor functions. @@ -62,12 +62,12 @@ class e2sm_rc_control_action_2_6_du_executor : public e2sm_rc_control_action_du_ void parse_action_ran_parameter_value(const asn1::e2sm::ran_param_value_type_c& ran_p, uint64_t ran_param_id, uint64_t ue_id, - du_mac_sched_control_config& ctrl_cfg) override; + srs_du::du_mac_sched_control_config& ctrl_cfg) override; private: - du_mac_sched_control_config convert_to_du_config_request(const e2sm_ric_control_request& e2sm_req_); - e2sm_ric_control_response convert_to_e2sm_response(const du_mac_sched_control_config& du_config_req_, - const du_mac_sched_control_config_response& du_reponse_); + srs_du::du_mac_sched_control_config convert_to_du_config_request(const e2sm_ric_control_request& e2sm_req_); + e2sm_ric_control_response convert_to_e2sm_response(const srs_du::du_mac_sched_control_config& du_config_req_, + const srs_du::du_mac_sched_control_config_response& du_reponse_); }; } // namespace srsran diff --git a/lib/f1ap/du/procedures/f1ap_du_event_manager.h b/lib/f1ap/du/procedures/f1ap_du_event_manager.h index eeebea4067..91502f6b6a 100644 --- a/lib/f1ap/du/procedures/f1ap_du_event_manager.h +++ b/lib/f1ap/du/procedures/f1ap_du_event_manager.h @@ -27,7 +27,7 @@ using f1ap_transaction = protocol_transaction; class f1ap_event_manager { /// Transaction Response Container, which gets indexed by transaction_id. - constexpr static size_t MAX_NOF_TRANSACTIONS = 256; + static constexpr size_t MAX_NOF_TRANSACTIONS = 256; public: protocol_transaction_manager transactions; diff --git a/lib/fapi/message_buffering/buffered_slot_gateway_impl.cpp b/lib/fapi/message_buffering/buffered_slot_gateway_impl.cpp index c8334390b3..b69d139e52 100644 --- a/lib/fapi/message_buffering/buffered_slot_gateway_impl.cpp +++ b/lib/fapi/message_buffering/buffered_slot_gateway_impl.cpp @@ -14,7 +14,7 @@ using namespace srsran; using namespace fapi; -buffered_slot_gateway_impl::buffered_slot_gateway_impl(unsigned int l2_nof_slots_ahead_, +buffered_slot_gateway_impl::buffered_slot_gateway_impl(unsigned l2_nof_slots_ahead_, subcarrier_spacing scs_, slot_message_gateway& gateway_) : l2_nof_slots_ahead(l2_nof_slots_ahead_), scs(scs_), gateway(gateway_), logger(srslog::fetch_basic_logger("FAPI")) diff --git a/lib/gateways/sctp_network_gateway_common_impl.h b/lib/gateways/sctp_network_gateway_common_impl.h index ffea9dfda4..6cef2a17d0 100644 --- a/lib/gateways/sctp_network_gateway_common_impl.h +++ b/lib/gateways/sctp_network_gateway_common_impl.h @@ -44,7 +44,7 @@ class sctp_network_gateway_common_impl ~sctp_network_gateway_common_impl(); protected: - constexpr static uint32_t network_gateway_sctp_max_len = 9100; + static constexpr uint32_t network_gateway_sctp_max_len = 9100; // Close socket and unsubscribe it from the io_broker. bool close_socket(); diff --git a/lib/mac/config/mac_cell_group_config_factory.cpp b/lib/mac/config/mac_cell_group_config_factory.cpp index b6f9385811..80e778f5c7 100644 --- a/lib/mac/config/mac_cell_group_config_factory.cpp +++ b/lib/mac/config/mac_cell_group_config_factory.cpp @@ -17,7 +17,8 @@ using namespace srsran; -mac_cell_group_config config_helpers::make_initial_mac_cell_group_config(const mac_cell_group_params& mcg_params) +mac_cell_group_config +config_helpers::make_initial_mac_cell_group_config(const srs_du::mac_cell_group_params& mcg_params) { mac_cell_group_config mcg_cfg{}; scheduling_request_to_addmod sr_0{.sr_id = scheduling_request_id::SR_ID_MIN, diff --git a/lib/mac/config/mac_config_helpers.cpp b/lib/mac/config/mac_config_helpers.cpp index a8a26fbd3a..14d2486452 100644 --- a/lib/mac/config/mac_config_helpers.cpp +++ b/lib/mac/config/mac_config_helpers.cpp @@ -14,9 +14,9 @@ using namespace srsran; /// Derives MAC Cell Configuration from DU Cell Configuration. -mac_cell_creation_request srsran::make_mac_cell_config(du_cell_index_t cell_index, - const du_cell_config& du_cfg, - std::vector bcch_dl_sch_payloads, +mac_cell_creation_request srsran::make_mac_cell_config(du_cell_index_t cell_index, + const srs_du::du_cell_config& du_cfg, + std::vector bcch_dl_sch_payloads, const sched_cell_configuration_request_message& sched_cell_cfg) { mac_cell_creation_request mac_cfg{}; diff --git a/lib/mac/mac_ctrl/mac_config.h b/lib/mac/mac_ctrl/mac_config.h index ad83f396ea..635e28e98c 100644 --- a/lib/mac/mac_ctrl/mac_config.h +++ b/lib/mac/mac_ctrl/mac_config.h @@ -21,16 +21,16 @@ namespace srsran { struct mac_control_config { - srslog::basic_logger& logger; - mac_ul_ccch_notifier& event_notifier; - du_high_ue_executor_mapper& ue_exec_mapper; - du_high_cell_executor_mapper& cell_exec_mapper; - task_executor& ctrl_exec; + srslog::basic_logger& logger; + mac_ul_ccch_notifier& event_notifier; + srs_du::du_high_ue_executor_mapper& ue_exec_mapper; + srs_du::du_high_cell_executor_mapper& cell_exec_mapper; + task_executor& ctrl_exec; - mac_control_config(mac_ul_ccch_notifier& event_notifier_, - du_high_ue_executor_mapper& ul_exec_, - du_high_cell_executor_mapper& dl_exec_, - task_executor& ctrl_exec_) : + mac_control_config(mac_ul_ccch_notifier& event_notifier_, + srs_du::du_high_ue_executor_mapper& ul_exec_, + srs_du::du_high_cell_executor_mapper& dl_exec_, + task_executor& ctrl_exec_) : logger(srslog::fetch_basic_logger("MAC", true)), event_notifier(event_notifier_), ue_exec_mapper(ul_exec_), diff --git a/lib/mac/mac_dl/mac_dl_processor.h b/lib/mac/mac_dl/mac_dl_processor.h index 6ea8b4b5b9..168ed06f6a 100644 --- a/lib/mac/mac_dl/mac_dl_processor.h +++ b/lib/mac/mac_dl/mac_dl_processor.h @@ -21,11 +21,11 @@ namespace srsran { struct mac_dl_config { - du_high_ue_executor_mapper& ue_exec_mapper; - du_high_cell_executor_mapper& cell_exec_mapper; - task_executor& ctrl_exec; - mac_result_notifier& phy_notifier; - mac_pcap& pcap; + srs_du::du_high_ue_executor_mapper& ue_exec_mapper; + srs_du::du_high_cell_executor_mapper& cell_exec_mapper; + task_executor& ctrl_exec; + mac_result_notifier& phy_notifier; + mac_pcap& pcap; }; class mac_dl_processor final : public mac_dl_configurator diff --git a/lib/mac/mac_dl/mac_dl_ue_repository.h b/lib/mac/mac_dl/mac_dl_ue_repository.h index 466834b8a8..f163460d16 100644 --- a/lib/mac/mac_dl/mac_dl_ue_repository.h +++ b/lib/mac/mac_dl/mac_dl_ue_repository.h @@ -21,7 +21,7 @@ namespace srsran { // Array of bytes used to store the UE Contention Resolution Id. -constexpr static size_t UE_CON_RES_ID_LEN = 6; +static constexpr size_t UE_CON_RES_ID_LEN = 6; using ue_con_res_id_t = std::array; // Table for conversion between RNTI and ue indexes. diff --git a/lib/mac/mac_ul/mac_ul_processor.h b/lib/mac/mac_ul/mac_ul_processor.h index 403f16c918..12ad0095d1 100644 --- a/lib/mac/mac_ul/mac_ul_processor.h +++ b/lib/mac/mac_ul/mac_ul_processor.h @@ -22,12 +22,12 @@ namespace srsran { struct mac_ul_config { - task_executor& ctrl_exec; - du_high_ue_executor_mapper& ue_exec_mapper; - mac_ul_ccch_notifier& ul_ccch_notifier; - mac_scheduler_ce_info_handler& sched; - du_rnti_table& rnti_table; - mac_pcap& pcap; + task_executor& ctrl_exec; + srs_du::du_high_ue_executor_mapper& ue_exec_mapper; + mac_ul_ccch_notifier& ul_ccch_notifier; + mac_scheduler_ce_info_handler& sched; + du_rnti_table& rnti_table; + mac_pcap& pcap; }; class mac_ul_processor final : public mac_ul_configurator, public mac_pdu_handler diff --git a/lib/mac/mac_ul/pdu_rx_handler.cpp b/lib/mac/mac_ul/pdu_rx_handler.cpp index bb58a2c6ac..5cfa897249 100644 --- a/lib/mac/mac_ul/pdu_rx_handler.cpp +++ b/lib/mac/mac_ul/pdu_rx_handler.cpp @@ -54,12 +54,12 @@ struct fmt::formatter : public basic_fmt_parser { } }; -pdu_rx_handler::pdu_rx_handler(mac_ul_ccch_notifier& ccch_notifier_, - du_high_ue_executor_mapper& ue_exec_mapper_, - mac_scheduler_ce_info_handler& sched_, - mac_ul_ue_manager& ue_manager_, - du_rnti_table& rnti_table_, - mac_pcap& pcap_) : +pdu_rx_handler::pdu_rx_handler(mac_ul_ccch_notifier& ccch_notifier_, + srs_du::du_high_ue_executor_mapper& ue_exec_mapper_, + mac_scheduler_ce_info_handler& sched_, + mac_ul_ue_manager& ue_manager_, + du_rnti_table& rnti_table_, + mac_pcap& pcap_) : ccch_notifier(ccch_notifier_), ue_exec_mapper(ue_exec_mapper_), logger(srslog::fetch_basic_logger("MAC")), diff --git a/lib/mac/mac_ul/pdu_rx_handler.h b/lib/mac/mac_ul/pdu_rx_handler.h index 1426904665..e3ad03b737 100644 --- a/lib/mac/mac_ul/pdu_rx_handler.h +++ b/lib/mac/mac_ul/pdu_rx_handler.h @@ -70,12 +70,12 @@ struct decoded_mac_rx_pdu { class pdu_rx_handler { public: - pdu_rx_handler(mac_ul_ccch_notifier& ccch_notifier_, - du_high_ue_executor_mapper& ue_exec_mapper_, - mac_scheduler_ce_info_handler& sched_, - mac_ul_ue_manager& ue_manager_, - du_rnti_table& rnti_table_, - mac_pcap& pcap_); + pdu_rx_handler(mac_ul_ccch_notifier& ccch_notifier_, + srs_du::du_high_ue_executor_mapper& ue_exec_mapper_, + mac_scheduler_ce_info_handler& sched_, + mac_ul_ue_manager& ue_manager_, + du_rnti_table& rnti_table_, + mac_pcap& pcap_); /// Decode MAC Rx PDU, log contents and handle subPDUs. /// \param sl_rx Slot when MAC UL PDU was received. @@ -122,13 +122,13 @@ class pdu_rx_handler /// Handle PDU to PCAP file void write_pcap_rx_pdu(const slot_point& sl_rx, const mac_rx_pdu& pdu); - mac_ul_ccch_notifier& ccch_notifier; - du_high_ue_executor_mapper& ue_exec_mapper; - srslog::basic_logger& logger; - mac_scheduler_ce_info_handler& sched; - mac_ul_ue_manager& ue_manager; - du_rnti_table& rnti_table; - mac_pcap& pcap; + mac_ul_ccch_notifier& ccch_notifier; + srs_du::du_high_ue_executor_mapper& ue_exec_mapper; + srslog::basic_logger& logger; + mac_scheduler_ce_info_handler& sched; + mac_ul_ue_manager& ue_manager; + du_rnti_table& rnti_table; + mac_pcap& pcap; }; } // namespace srsran diff --git a/lib/pcap/pcap_file_writer.h b/lib/pcap/pcap_file_writer.h index cb4e41fa3c..29979a72f5 100644 --- a/lib/pcap/pcap_file_writer.h +++ b/lib/pcap/pcap_file_writer.h @@ -22,21 +22,21 @@ namespace srsran { /// This structure gets written to the start of the file struct pcap_hdr_t { - unsigned int magic_number; /// magic number + unsigned magic_number; /// magic number unsigned short version_major; /// major version number unsigned short version_minor; /// minor version number - unsigned int thiszone; /// GMT to local correction - unsigned int sigfigs; /// accuracy of timestamps - unsigned int snaplen; /// max length of captured packets, in octets - unsigned int network; /// data link type + unsigned thiszone; /// GMT to local correction + unsigned sigfigs; /// accuracy of timestamps + unsigned snaplen; /// max length of captured packets, in octets + unsigned network; /// data link type }; /// This structure precedes each packet struct pcaprec_hdr_t { - unsigned int ts_sec; /// timestamp seconds - unsigned int ts_usec; /// timestamp microseconds - unsigned int incl_len; /// number of octets of packet saved in file - unsigned int orig_len; /// actual length of packet + unsigned ts_sec; /// timestamp seconds + unsigned ts_usec; /// timestamp microseconds + unsigned incl_len; /// number of octets of packet saved in file + unsigned orig_len; /// actual length of packet }; /// @brief Base class for PCAP writing to files. diff --git a/lib/pcap/rlc_pcap_impl.cpp b/lib/pcap/rlc_pcap_impl.cpp index 52e1f357b0..7ac208a7b5 100644 --- a/lib/pcap/rlc_pcap_impl.cpp +++ b/lib/pcap/rlc_pcap_impl.cpp @@ -26,7 +26,7 @@ constexpr uint8_t PCAP_RLC_NR_BEARER_ID_TAG = 0x05; // Other constants constexpr uint16_t UDP_DLT = 149; -int nr_pcap_pack_rlc_context_to_buffer(const pcap_rlc_pdu_context& context, uint8_t* buffer, unsigned int length); +int nr_pcap_pack_rlc_context_to_buffer(const pcap_rlc_pdu_context& context, uint8_t* buffer, unsigned length); rlc_pcap_impl::rlc_pcap_impl(const std::string& filename_, bool capture_srb, @@ -122,7 +122,7 @@ void rlc_pcap_impl::push_pdu(const pcap_rlc_pdu_context& context, const byte_buf } /// Helper function to serialize RLC NR context -int nr_pcap_pack_rlc_context_to_buffer(const pcap_rlc_pdu_context& context, uint8_t* buffer, unsigned int length) +int nr_pcap_pack_rlc_context_to_buffer(const pcap_rlc_pdu_context& context, uint8_t* buffer, unsigned length) { int offset = {}; uint16_t tmp16 = {}; diff --git a/lib/pdcp/pdcp_pdu.h b/lib/pdcp/pdcp_pdu.h index b2b27611c5..062525cdd9 100644 --- a/lib/pdcp/pdcp_pdu.h +++ b/lib/pdcp/pdcp_pdu.h @@ -91,7 +91,7 @@ struct formatter { template auto format(srsran::pdcp_dc_field dc, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"ctrl", "data"}; + static constexpr const char* options[] = {"ctrl", "data"}; return format_to(ctx.out(), "{}", options[to_number(dc)]); } }; @@ -107,7 +107,7 @@ struct formatter { template auto format(srsran::pdcp_control_pdu_type cpt, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"status_report", "rohc_feedback", "ehc_feedback"}; + static constexpr const char* options[] = {"status_report", "rohc_feedback", "ehc_feedback"}; return format_to(ctx.out(), "{}", options[to_number(cpt)]); } }; diff --git a/lib/phy/generic_functions/dft_processor_fftw_impl.h b/lib/phy/generic_functions/dft_processor_fftw_impl.h index d6d1747c5d..a56b079489 100644 --- a/lib/phy/generic_functions/dft_processor_fftw_impl.h +++ b/lib/phy/generic_functions/dft_processor_fftw_impl.h @@ -110,7 +110,7 @@ class dft_processor_fftw_impl : public dft_processor direction get_direction() const override { return dir; } // See interface for documentation. - unsigned int get_size() const override { return input.size(); } + unsigned get_size() const override { return input.size(); } // See interface for documentation. span get_input() override { return input; } diff --git a/lib/phy/generic_functions/dft_processor_generic_impl.h b/lib/phy/generic_functions/dft_processor_generic_impl.h index 5568247439..20f7ef8a64 100644 --- a/lib/phy/generic_functions/dft_processor_generic_impl.h +++ b/lib/phy/generic_functions/dft_processor_generic_impl.h @@ -49,7 +49,7 @@ class dft_processor_generic_impl : public dft_processor direction get_direction() const override { return dir; } // See interface for documentation. - unsigned int get_size() const override { return input.size(); } + unsigned get_size() const override { return input.size(); } // See interface for documentation. span get_input() override { return input; } diff --git a/lib/phy/support/prach_buffer_impl.h b/lib/phy/support/prach_buffer_impl.h index 4e5aff91d4..20ce01730c 100644 --- a/lib/phy/support/prach_buffer_impl.h +++ b/lib/phy/support/prach_buffer_impl.h @@ -45,7 +45,7 @@ class prach_buffer_impl : public prach_buffer } // See interface for documentation. - unsigned int get_max_nof_ports() const override { return data.get_dimension_size(dims::port); } + unsigned get_max_nof_ports() const override { return data.get_dimension_size(dims::port); } // See interface for documentation. unsigned get_max_nof_td_occasions() const override { return data.get_dimension_size(dims::td_occasion); } diff --git a/lib/phy/upper/channel_coding/ldpc/ldpc_encoder_neon.cpp b/lib/phy/upper/channel_coding/ldpc/ldpc_encoder_neon.cpp index a3267954ee..0a14e63f2d 100644 --- a/lib/phy/upper/channel_coding/ldpc/ldpc_encoder_neon.cpp +++ b/lib/phy/upper/channel_coding/ldpc/ldpc_encoder_neon.cpp @@ -27,7 +27,7 @@ static constexpr unsigned MAX_NODE_SIZE_NEON = divide_ceil(ldpc::MAX_LIFTING_SIZ template ldpc_encoder_neon::strategy_method ldpc_encoder_neon::select_hr_strategy(ldpc_base_graph_type current_bg, uint8_t current_ls_index, - unsigned int node_size_neon) + unsigned node_size_neon) { if (node_size_neon != NODE_SIZE_NEON_PH) { return select_hr_strategy(current_bg, current_ls_index, node_size_neon); @@ -462,4 +462,4 @@ void ldpc_encoder_neon::write_codeblock(span out, unsigned offset) cons // The offset is no longer required after the first node. offset = 0; } -} \ No newline at end of file +} diff --git a/lib/phy/upper/channel_processors/pusch/pusch_decoder_hw_impl.cpp b/lib/phy/upper/channel_processors/pusch/pusch_decoder_hw_impl.cpp index 2fece7743f..e037d91129 100644 --- a/lib/phy/upper/channel_processors/pusch/pusch_decoder_hw_impl.cpp +++ b/lib/phy/upper/channel_processors/pusch/pusch_decoder_hw_impl.cpp @@ -347,7 +347,7 @@ void pusch_decoder_hw_impl::run_asynch_hw_decoder() void pusch_decoder_hw_impl::check_hw_results(span cb_crcs, hal::hw_accelerator_pusch_dec& decoder, - unsigned int cb_id, + unsigned cb_id, hal::hw_dec_cb_crc_type crc_type, srsran::bit_buffer data) { diff --git a/lib/phy/upper/signal_processors/dmrs_pdcch_processor_impl.cpp b/lib/phy/upper/signal_processors/dmrs_pdcch_processor_impl.cpp index 7155d453ba..3ec71b5345 100644 --- a/lib/phy/upper/signal_processors/dmrs_pdcch_processor_impl.cpp +++ b/lib/phy/upper/signal_processors/dmrs_pdcch_processor_impl.cpp @@ -26,7 +26,7 @@ unsigned dmrs_pdcch_processor_impl::c_init(unsigned symbol, const dmrs_pdcch_pro } void dmrs_pdcch_processor_impl::sequence_generation(span sequence, - unsigned int symbol, + unsigned symbol, const dmrs_pdcch_processor::config_t& config) const { // Initialize pseudo-random generator. diff --git a/lib/phy/upper/vrb_to_prb_mapper.cpp b/lib/phy/upper/vrb_to_prb_mapper.cpp index 07a3744955..648bdbeb53 100644 --- a/lib/phy/upper/vrb_to_prb_mapper.cpp +++ b/lib/phy/upper/vrb_to_prb_mapper.cpp @@ -134,7 +134,7 @@ vrb_to_prb_mapper::create_interleaved_common(unsigned N_start_coreset, unsigned } vrb_to_prb_mapper -vrb_to_prb_mapper::create_interleaved_other(unsigned int N_bwp_i_start, unsigned int N_bwp_i_size, unsigned int L_i) +vrb_to_prb_mapper::create_interleaved_other(unsigned N_bwp_i_start, unsigned N_bwp_i_size, unsigned L_i) { vrb_to_prb_mapper mapper; @@ -164,4 +164,4 @@ static_vector vrb_to_prb_mapper::get_allocation_indices(unsign } return result; -} \ No newline at end of file +} diff --git a/lib/ran/band_helper.cpp b/lib/ran/band_helper.cpp index d68a5b9018..5e468832a1 100644 --- a/lib/ran/band_helper.cpp +++ b/lib/ran/band_helper.cpp @@ -960,7 +960,7 @@ frequency_range srsran::band_helper::get_freq_range(nr_band band) double srsran::band_helper::get_abs_freq_point_a_from_center_freq(uint32_t nof_prb, double center_freq) { - constexpr static unsigned NRE = 12; + static constexpr unsigned NRE = 12; // For FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier. // TODO: add offset_to_carrier. @@ -974,7 +974,7 @@ uint32_t srsran::band_helper::get_abs_freq_point_a_arfcn(uint32_t nof_prb, uint3 double srsran::band_helper::get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn) { - constexpr static unsigned NRE = 12; + static constexpr unsigned NRE = 12; // for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier. // TODO: add offset_to_carrier const double abs_freq_point_a_freq = nr_arfcn_to_freq(freq_point_a_arfcn); @@ -990,7 +990,7 @@ double srsran::band_helper::get_abs_freq_point_a_from_f_ref(double f_ref, uint32 // supported by the BS.<\em>. Therefore, the correct SCS to be used in this procedure still needs to determined. // Half of the number of subcarriers in a RE. - constexpr static unsigned NRE_half = 6; + static constexpr unsigned NRE_half = 6; // The procedure, which is explained in TS 38.104, Section 5.4.2.2, gives the position of f_ref in terms of subcarrier // and CRB index, depending on the size of N_RB. Below we compute the value in unit of subcarriers, meaning we don't @@ -1005,7 +1005,7 @@ srsran::band_helper::get_f_ref_from_abs_freq_point_a(double abs_freq_point_a, ui // See notes in \ref get_abs_freq_point_a_from_f_ref. // Half of the number of subcarriers in a RE. - constexpr static unsigned NRE_half = 6; + static constexpr unsigned NRE_half = 6; // The procedure used in this function is the inverse of what explained in TS 38.104, Section 5.4.2.2. const unsigned delta_point_a_f_ref = nof_rbs * NRE_half; return abs_freq_point_a + static_cast(delta_point_a_f_ref * scs_to_khz(scs) * KHZ_TO_HZ); diff --git a/lib/ran/resource_allocation/resource_allocation_frequency.cpp b/lib/ran/resource_allocation/resource_allocation_frequency.cpp index ceecb81f00..07a72c2d40 100644 --- a/lib/ran/resource_allocation/resource_allocation_frequency.cpp +++ b/lib/ran/resource_allocation/resource_allocation_frequency.cpp @@ -14,7 +14,7 @@ using namespace srsran; -unsigned int srsran::ra_frequency_type1_get_riv(const ra_frequency_type1_configuration& config) +unsigned srsran::ra_frequency_type1_get_riv(const ra_frequency_type1_configuration& config) { srsran_assert(config.length_vrb >= 1, "The number of contiguous allocated blocks must be greater than or equal to 1."); diff --git a/lib/rlc/rlc_am_pdu.h b/lib/rlc/rlc_am_pdu.h index 695c32b45c..67136f2910 100644 --- a/lib/rlc/rlc_am_pdu.h +++ b/lib/rlc/rlc_am_pdu.h @@ -76,7 +76,7 @@ struct rlc_am_pdu_header { /// Status PDU NACK struct rlc_am_status_nack { - const static uint16_t so_end_of_sdu; + static const uint16_t so_end_of_sdu; uint32_t nack_sn; ///< Sequence Number (SN) of first missing SDU bool has_so; ///< NACKs continuous sequence of bytes [so_start..so_end] diff --git a/lib/rrc/ue/procedures/rrc_ue_event_manager.h b/lib/rrc/ue/procedures/rrc_ue_event_manager.h index fd8ba9b3f5..2e45378e66 100644 --- a/lib/rrc/ue/procedures/rrc_ue_event_manager.h +++ b/lib/rrc/ue/procedures/rrc_ue_event_manager.h @@ -25,7 +25,7 @@ class rrc_ue_event_manager { public: /// Transaction Response Container, which gets indexed by transaction_id. - constexpr static size_t MAX_NOF_TRANSACTIONS = 4; // Two bit RRC transaction id + static constexpr size_t MAX_NOF_TRANSACTIONS = 4; // Two bit RRC transaction id protocol_transaction_manager transactions; explicit rrc_ue_event_manager(timer_factory timers) : transactions(MAX_NOF_TRANSACTIONS, timers) {} diff --git a/lib/ru/dummy/ru_dummy_rx_prach_buffer.h b/lib/ru/dummy/ru_dummy_rx_prach_buffer.h index 3520f5f8b1..0e7c9d826a 100644 --- a/lib/ru/dummy/ru_dummy_rx_prach_buffer.h +++ b/lib/ru/dummy/ru_dummy_rx_prach_buffer.h @@ -76,7 +76,7 @@ class ru_dummy_rx_prach_buffer : private prach_buffer private: // See interface for documentation. - unsigned int get_max_nof_ports() const override { return data.get_dimension_size(dims::port); } + unsigned get_max_nof_ports() const override { return data.get_dimension_size(dims::port); } // See interface for documentation. unsigned get_max_nof_td_occasions() const override { return data.get_dimension_size(dims::td_occasion); } diff --git a/lib/scheduler/cell/cell_harq_manager.h b/lib/scheduler/cell/cell_harq_manager.h index af809ba0f5..2bd606f093 100644 --- a/lib/scheduler/cell/cell_harq_manager.h +++ b/lib/scheduler/cell/cell_harq_manager.h @@ -242,7 +242,7 @@ class dl_harq_process_handle : public harq_utils::base_harq_process_handle public: /// \brief Timeout value to use when the HARQ has been ACKed/NACKed, but it is expecting another PUCCH before being /// cleared (implementation-defined). - constexpr static unsigned SHORT_ACK_TIMEOUT_DTX = 8U; + static constexpr unsigned SHORT_ACK_TIMEOUT_DTX = 8U; using status_update = harq_utils::dl_harq_process_impl::status_update; using grant_params = harq_utils::dl_harq_process_impl::alloc_params; @@ -394,7 +394,7 @@ class cell_harq_manager public: /// \brief Default timeout in slots after which the HARQ process assumes that the CRC/ACK went missing /// (implementation-defined). - constexpr static unsigned DEFAULT_ACK_TIMEOUT_SLOTS = 256U; + static constexpr unsigned DEFAULT_ACK_TIMEOUT_SLOTS = 256U; cell_harq_manager(unsigned max_ues = MAX_NOF_DU_UES, unsigned max_harqs_per_ue = MAX_NOF_HARQS, diff --git a/lib/scheduler/common_scheduling/ra_scheduler.cpp b/lib/scheduler/common_scheduling/ra_scheduler.cpp index 748f3c872c..03b319ec55 100644 --- a/lib/scheduler/common_scheduling/ra_scheduler.cpp +++ b/lib/scheduler/common_scheduling/ra_scheduler.cpp @@ -205,7 +205,7 @@ void ra_scheduler::handle_rach_indication(const rach_indication_message& msg) void ra_scheduler::handle_rach_indication_impl(const rach_indication_message& msg) { - const static unsigned prach_duration = 1; // TODO: Take from config + static const unsigned prach_duration = 1; // TODO: Take from config for (const auto& prach_occ : msg.occasions) { // As per Section 5.1.3, TS 38.321, and from Section 5.3.2, TS 38.211, slot_idx uses as the numerology of reference @@ -612,7 +612,7 @@ unsigned ra_scheduler::schedule_rar(const pending_rar_t& rar, cell_resource_allo rar_crbs.resize(get_nof_pdsch_prbs_required(pdsch_time_res_index, max_nof_allocs).nof_prbs); // > Find space in PDCCH for RAR. - const static aggregation_level aggr_lvl = aggregation_level::n4; + static const aggregation_level aggr_lvl = aggregation_level::n4; const search_space_id ss_id = cell_cfg.dl_cfg_common.init_dl_bwp.pdcch_common.ra_search_space_id; pdcch_dl_information* pdcch = pdcch_sch.alloc_dl_pdcch_common(pdcch_alloc, rar.ra_rnti, ss_id, aggr_lvl); if (pdcch == nullptr) { diff --git a/lib/scheduler/config/sched_cell_config_helpers.cpp b/lib/scheduler/config/sched_cell_config_helpers.cpp index 18af5928fa..62066ddb99 100644 --- a/lib/scheduler/config/sched_cell_config_helpers.cpp +++ b/lib/scheduler/config/sched_cell_config_helpers.cpp @@ -17,7 +17,7 @@ using namespace srsran; using namespace srsran::config_helpers; std::vector -srsran::config_helpers::build_pucch_guardbands_list(const pucch_builder_params& user_params, unsigned bwp_size) +srsran::config_helpers::build_pucch_guardbands_list(const srs_du::pucch_builder_params& user_params, unsigned bwp_size) { // Compute the cell PUCCH resource list, depending on which parameter that has been passed. std::vector res_list = srs_du::generate_cell_pucch_res_list( diff --git a/lib/scheduler/config/serving_cell_config_factory.cpp b/lib/scheduler/config/serving_cell_config_factory.cpp index 1419ef8906..319c47df98 100644 --- a/lib/scheduler/config/serving_cell_config_factory.cpp +++ b/lib/scheduler/config/serving_cell_config_factory.cpp @@ -103,7 +103,7 @@ static carrier_configuration make_default_carrier_configuration(const cell_confi static_vector srsran::config_helpers::generate_k1_candidates(const tdd_ul_dl_config_common& tdd_cfg, uint8_t min_k1) { - const static unsigned MAX_K1_CANDIDATES = 8; + static const unsigned MAX_K1_CANDIDATES = 8; const unsigned tdd_period = nof_slots_per_tdd_period(tdd_cfg); unsigned nof_dl_slots = tdd_cfg.pattern1.nof_dl_slots + (tdd_cfg.pattern1.nof_dl_symbols > 0 ? 1 : 0); if (tdd_cfg.pattern2.has_value()) { @@ -647,7 +647,7 @@ uplink_config srsran::config_helpers::make_default_ue_uplink_config(const cell_c // Compute the max UCI payload per format. // As per TS 38.231, Section 9.2.1, with PUCCH Format 1, we can have up to 2 HARQ-ACK bits (SR doesn't count as part // of the payload). - constexpr static unsigned pucch_f1_max_harq_payload = 2U; + static constexpr unsigned pucch_f1_max_harq_payload = 2U; pucch_cfg.format_max_payload[pucch_format_to_uint(pucch_format::FORMAT_1)] = pucch_f1_max_harq_payload; const auto& res_f2 = std::get(res_basic_f2.format_params); pucch_cfg.format_max_payload[pucch_format_to_uint(pucch_format::FORMAT_2)] = get_pucch_format2_max_payload( diff --git a/lib/scheduler/pucch_scheduling/pucch_allocator_impl.h b/lib/scheduler/pucch_scheduling/pucch_allocator_impl.h index 2a9f39087a..9eb725b1e4 100644 --- a/lib/scheduler/pucch_scheduling/pucch_allocator_impl.h +++ b/lib/scheduler/pucch_scheduling/pucch_allocator_impl.h @@ -246,7 +246,7 @@ class pucch_allocator_impl final : public pucch_allocator // \brief Ring of PUCCH allocations indexed by slot. circular_array pucch_grants_alloc_grid; - constexpr static unsigned PUCCH_FORMAT_0_1_NOF_PRBS{1}; + static constexpr unsigned PUCCH_FORMAT_0_1_NOF_PRBS{1}; const cell_configuration& cell_cfg; const unsigned max_pucch_grants_per_slot; const unsigned max_ul_grants_per_slot; diff --git a/lib/scheduler/slicing/slice_scheduler.cpp b/lib/scheduler/slicing/slice_scheduler.cpp index 11eab4ffca..7af3c6c1fd 100644 --- a/lib/scheduler/slicing/slice_scheduler.cpp +++ b/lib/scheduler/slicing/slice_scheduler.cpp @@ -277,11 +277,11 @@ slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_pri // 3. round-robin based on slot indication count (8 least significant bits). // Priority when slice has already reached its minimum RB ratio agreement. - constexpr static priority_type default_prio = 0x1U; + static constexpr priority_type default_prio = 0x1U; // Priority when slice still needs to reach its minimum RB ratio agreement. - constexpr static priority_type high_prio = 0x2U; - constexpr static priority_type delay_bitsize = 8U; - constexpr static priority_type rr_bitsize = 8U; + static constexpr priority_type high_prio = 0x2U; + static constexpr priority_type delay_bitsize = 8U; + static constexpr priority_type rr_bitsize = 8U; unsigned rb_count = is_dl ? inst.pdsch_rb_count : inst.pusch_rb_count_per_slot[slot_tx.to_uint()]; if (not inst.active() or rb_count >= inst.cfg.max_prb) { diff --git a/lib/scheduler/slicing/slice_scheduler.h b/lib/scheduler/slicing/slice_scheduler.h index dee7595280..8c545ab1e9 100644 --- a/lib/scheduler/slicing/slice_scheduler.h +++ b/lib/scheduler/slicing/slice_scheduler.h @@ -22,7 +22,7 @@ class slice_scheduler { using priority_type = uint32_t; using slot_count_type = uint32_t; - constexpr static priority_type skip_prio = 0; + static constexpr priority_type skip_prio = 0; public: slice_scheduler(const cell_configuration& cell_cfg_, ue_repository& ues_); diff --git a/lib/scheduler/slicing/slice_ue_repository.cpp b/lib/scheduler/slicing/slice_ue_repository.cpp index 3dd7638d9d..6f2ec87b00 100644 --- a/lib/scheduler/slicing/slice_ue_repository.cpp +++ b/lib/scheduler/slicing/slice_ue_repository.cpp @@ -66,7 +66,7 @@ unsigned slice_ue::pending_dl_newtx_bytes() const unsigned slice_ue::pending_ul_newtx_bytes() const { - constexpr static unsigned SR_GRANT_BYTES = 512; + static constexpr unsigned SR_GRANT_BYTES = 512; unsigned pending_bytes = 0; for (unsigned lcg_id = 0, e = lcg_ids.size(); lcg_id != e; ++lcg_id) { diff --git a/lib/scheduler/support/pucch/pucch_default_resource.cpp b/lib/scheduler/support/pucch/pucch_default_resource.cpp index 4da0d0cde5..4537ae92d4 100644 --- a/lib/scheduler/support/pucch/pucch_default_resource.cpp +++ b/lib/scheduler/support/pucch/pucch_default_resource.cpp @@ -12,7 +12,7 @@ using namespace srsran; -unsigned srsran::get_pucch_default_resource_index(unsigned int n_cce, unsigned int nof_cce, unsigned int delta_pri) +unsigned srsran::get_pucch_default_resource_index(unsigned n_cce, unsigned nof_cce, unsigned delta_pri) { return (2 * n_cce) / nof_cce + 2 * delta_pri; } @@ -73,4 +73,4 @@ pucch_default_resource srsran::get_pucch_default_resource(unsigned index, unsign } return result; -} \ No newline at end of file +} diff --git a/lib/scheduler/ue_scheduling/harq_process.h b/lib/scheduler/ue_scheduling/harq_process.h index a2cabbc852..cfabbc52f8 100644 --- a/lib/scheduler/ue_scheduling/harq_process.h +++ b/lib/scheduler/ue_scheduling/harq_process.h @@ -121,14 +121,14 @@ class harq_process public: /// \brief Default timeout in slots after which the HARQ process assumes that the CRC/ACK went missing /// (implementation-defined). - constexpr static unsigned DEFAULT_ACK_TIMEOUT_SLOTS = 256U; + static constexpr unsigned DEFAULT_ACK_TIMEOUT_SLOTS = 256U; /// \brief Timeout value to use when the HARQ has been ACKed/NACKed, but it is expecting another PUCCH before being /// cleared (implementation-defined). - constexpr static unsigned SHORT_ACK_TIMEOUT_DTX = 8U; + static constexpr unsigned SHORT_ACK_TIMEOUT_DTX = 8U; /// Maximum number of Transport Blocks as per TS38.321, 5.3.2.1 and 5.4.2.1. - constexpr static size_t MAX_NOF_TBS = IsDownlink ? 2 : 1; + static constexpr size_t MAX_NOF_TBS = IsDownlink ? 2 : 1; struct transport_block { /// State of the Transport Block. diff --git a/lib/scheduler/ue_scheduling/ue.cpp b/lib/scheduler/ue_scheduling/ue.cpp index 8cb39af7a3..a047ae3901 100644 --- a/lib/scheduler/ue_scheduling/ue.cpp +++ b/lib/scheduler/ue_scheduling/ue.cpp @@ -137,7 +137,7 @@ unsigned ue::pending_ul_srb_newtx_bytes() const unsigned ue::pending_ul_newtx_bytes() const { - constexpr static unsigned SR_GRANT_BYTES = 512; + static constexpr unsigned SR_GRANT_BYTES = 512; // Sum the last BSRs. unsigned pending_bytes = ul_lc_ch_mgr.pending_bytes(); diff --git a/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp b/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp index aa65569800..629633693c 100644 --- a/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp +++ b/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp @@ -487,7 +487,7 @@ ue_cell_grid_allocator::allocate_ul_grant(const ue_pusch_grant& grant, ran_slice { srsran_assert(ues.contains(grant.user->ue_index()), "Invalid UE candidate index={}", grant.user->ue_index()); srsran_assert(has_cell(grant.cell_index), "Invalid UE candidate cell_index={}", grant.cell_index); - constexpr static unsigned pdcch_delay_in_slots = 0; + static constexpr unsigned pdcch_delay_in_slots = 0; if (ul_attempts_count++ >= expert_cfg.max_pdcch_alloc_attempts_per_slot) { logger.debug("Stopping UL allocations. Cause: Max number of UL PDCCH allocation attempts {} reached.", diff --git a/lib/scheduler/ue_scheduling/ul_logical_channel_manager.h b/lib/scheduler/ue_scheduling/ul_logical_channel_manager.h index b5ad56f9a2..927c0be61b 100644 --- a/lib/scheduler/ue_scheduling/ul_logical_channel_manager.h +++ b/lib/scheduler/ue_scheduling/ul_logical_channel_manager.h @@ -101,7 +101,7 @@ class ul_logical_channel_manager static unsigned add_upper_layer_header_bytes(lcg_id_t lcgid, unsigned payload_bytes) { // Estimate of the number of bytes required for the upper layer header. - constexpr static unsigned RLC_HEADER_SIZE_ESTIMATE = 3U; + static constexpr unsigned RLC_HEADER_SIZE_ESTIMATE = 3U; if (payload_bytes == 0 or lcgid == 0) { // In case of no payload or LCG-ID == 0, there is no need to account for upper layer header. diff --git a/tests/benchmarks/du_high/du_high_benchmark.cpp b/tests/benchmarks/du_high/du_high_benchmark.cpp index 5c2efaa0cc..09d5397aba 100644 --- a/tests/benchmarks/du_high/du_high_benchmark.cpp +++ b/tests/benchmarks/du_high/du_high_benchmark.cpp @@ -664,7 +664,7 @@ class du_high_bench cfg.ran.cells[0].pucch_cfg.nof_ue_pucch_f0_or_f1_res_harq = 8; cfg.ran.cells[0].pucch_cfg.nof_cell_harq_pucch_res_sets = 4; auto& f1_params = cfg.ran.cells[0].pucch_cfg.f0_or_f1_params.emplace(); - f1_params.nof_cyc_shifts = srsran::nof_cyclic_shifts::six; + f1_params.nof_cyc_shifts = nof_cyclic_shifts::six; f1_params.occ_supported = true; cfg.ran.sched_cfg.ue.max_pucchs_per_slot = 61; cfg.ran.sched_cfg.ue.max_puschs_per_slot = 61; diff --git a/tests/benchmarks/rlc/rlc_am_rx_benchmark.cpp b/tests/benchmarks/rlc/rlc_am_rx_benchmark.cpp index 419d3b5bb5..faf4b56df8 100644 --- a/tests/benchmarks/rlc/rlc_am_rx_benchmark.cpp +++ b/tests/benchmarks/rlc/rlc_am_rx_benchmark.cpp @@ -320,7 +320,7 @@ struct formatter { template auto format(rx_order order, FormatContext& ctx) -> decltype(std::declval().out()) { - constexpr static const char* options[] = {"in order", "swapped edges", "reverse order", "even odd"}; + static constexpr const char* options[] = {"in order", "swapped edges", "reverse order", "even odd"}; return format_to(ctx.out(), "{}", options[static_cast(order)]); } }; diff --git a/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp b/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp index 8dee40b273..3bedb6d929 100644 --- a/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp +++ b/tests/benchmarks/scheduler/scheduler_multi_ue_benchmark.cpp @@ -223,7 +223,7 @@ class multi_ue_sched_simulator sched_dummy_metric_notifier metric_notif; scheduler_expert_config expert_cfg; cell_config_builder_params builder_params; - std::vector du_cell_cfgs; + std::vector du_cell_cfgs; srslog::basic_logger& logger; std::optional pucch_res_mng; diff --git a/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp b/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp index 970a2f96cc..ab54ab93c3 100644 --- a/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp +++ b/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp @@ -17,6 +17,7 @@ #include using namespace srsran; +using namespace srs_du; struct mac_event_interceptor { std::optional next_ul_sched_res; diff --git a/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h b/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h index d8cf99b239..0f4bb5e0e9 100644 --- a/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h +++ b/tests/integrationtests/du_high/test_utils/du_high_worker_manager.h @@ -39,9 +39,11 @@ struct du_high_worker_manager { task_worker_executor ctrl_exec{ctrl_worker}; static_vector cell_execs{{cell_workers[0]}, {cell_workers[1]}}; static_vector ue_execs{{ue_workers[0]}, {ue_workers[1]}}; - du_high_executor_mapper_impl exec_mapper{ - std::make_unique(std::initializer_list{&cell_execs[0], &cell_execs[1]}), - std::make_unique(std::initializer_list{&ue_execs[0], &ue_execs[1]}), + srs_du::du_high_executor_mapper_impl exec_mapper{ + std::make_unique( + std::initializer_list{&cell_execs[0], &cell_execs[1]}), + std::make_unique( + std::initializer_list{&ue_execs[0], &ue_execs[1]}), ctrl_exec, ctrl_exec, ctrl_exec}; diff --git a/tests/integrationtests/du_high_cu/cu_du_test.cpp b/tests/integrationtests/du_high_cu/cu_du_test.cpp index 610bde6289..f04fc91876 100644 --- a/tests/integrationtests/du_high_cu/cu_du_test.cpp +++ b/tests/integrationtests/du_high_cu/cu_du_test.cpp @@ -23,6 +23,7 @@ #include using namespace srsran; +using namespace srs_du; // Dummy classes required by DU struct phy_cell_dummy : public mac_cell_result_notifier { @@ -68,7 +69,7 @@ class cu_du_test : public ::testing::Test // create and start DU phy_dummy phy; - srsran::srs_du::du_high_configuration du_cfg{}; + du_high_configuration du_cfg{}; du_cfg.exec_mapper = &workers.exec_mapper; du_cfg.f1c_client = &f1c_gw; du_cfg.f1u_gw = &f1u_gw; diff --git a/tests/integrationtests/du_high_cu/cu_multi_du_test.cpp b/tests/integrationtests/du_high_cu/cu_multi_du_test.cpp index 0cab16a41f..fcf5f44666 100644 --- a/tests/integrationtests/du_high_cu/cu_multi_du_test.cpp +++ b/tests/integrationtests/du_high_cu/cu_multi_du_test.cpp @@ -32,7 +32,7 @@ class cu_multi_du_test : public du_high_cu_test_simulator, public ::testing::Tes public: cu_multi_du_test() : du_high_cu_test_simulator(create_test_sim_config(nof_dus)) {} - constexpr static unsigned nof_dus = 2; + static constexpr unsigned nof_dus = 2; }; constexpr unsigned cu_multi_du_test::nof_dus; diff --git a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp index 9540c80487..5d8e8d39f9 100644 --- a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp +++ b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp @@ -61,16 +61,17 @@ du_high_cu_cp_worker_manager::du_high_cu_cp_worker_manager(unsigned nof_dus) : t make_worker_and_executor(prefix_str + "-CELL"); make_worker_and_executor(prefix_str + "-UE"); - auto du_hi_cell_mapper = - std::make_unique(std::initializer_list{executors[prefix_str + "-CELL"]}); - auto du_hi_ue_mapper = std::make_unique( + auto du_hi_cell_mapper = std::make_unique( + std::initializer_list{executors[prefix_str + "-CELL"]}); + auto du_hi_ue_mapper = std::make_unique( std::initializer_list{executors[prefix_str + "-UE"]}); - du_hi_exec_mappers.push_back(std::make_unique(std::move(du_hi_cell_mapper), - std::move(du_hi_ue_mapper), - *executors[prefix_str + "-CTRL"], - *executors[prefix_str + "-CTRL"], - *executors[prefix_str + "-CTRL"])); + du_hi_exec_mappers.push_back( + std::make_unique(std::move(du_hi_cell_mapper), + std::move(du_hi_ue_mapper), + *executors[prefix_str + "-CTRL"], + *executors[prefix_str + "-CTRL"], + *executors[prefix_str + "-CTRL"])); } } @@ -170,7 +171,7 @@ void du_high_cu_test_simulator::start_dus() void du_high_cu_test_simulator::run_slot() { for (unsigned i = 0; i != dus.size(); ++i) { - du_high& du_hi = *dus[i]->du_high_inst; + srs_du::du_high& du_hi = *dus[i]->du_high_inst; // Signal slot indication to l2. du_hi.get_slot_handler(to_du_cell_index(0)).handle_slot_indication(dus[i]->next_slot); diff --git a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h index 7500dbb2f9..b3ed459438 100644 --- a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h +++ b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.h @@ -32,9 +32,9 @@ class du_high_cu_cp_worker_manager void stop(); - manual_task_worker test_worker; - std::map executors; - std::vector> du_hi_exec_mappers; + manual_task_worker test_worker; + std::map executors; + std::vector> du_hi_exec_mappers; private: std::map> workers; @@ -42,7 +42,7 @@ class du_high_cu_cp_worker_manager }; struct du_high_cu_cp_test_simulator_config { - std::vector> dus; + std::vector> dus; }; class du_high_cu_test_simulator @@ -54,7 +54,7 @@ class du_high_cu_test_simulator null_mac_pcap mac_pcap; null_rlc_pcap rlc_pcap; dummy_scheduler_ue_metrics_notifier ue_metrics_notifier; - std::unique_ptr du_high_inst; + std::unique_ptr du_high_inst; slot_point next_slot; diff --git a/tests/integrationtests/e2ap/e2ap_integration_test.cpp b/tests/integrationtests/e2ap/e2ap_integration_test.cpp index b102a865ab..6f73743bba 100644 --- a/tests/integrationtests/e2ap/e2ap_integration_test.cpp +++ b/tests/integrationtests/e2ap/e2ap_integration_test.cpp @@ -94,7 +94,7 @@ class e2ap_integration_test : public ::testing::Test srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; sctp_network_connector_config nw_config; @@ -172,7 +172,7 @@ class e2ap_gw_connector_integration_test : public ::testing::Test srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; cfg.gnb_id = {123, 22}; @@ -203,7 +203,7 @@ class e2ap_gw_connector_integration_test : public ::testing::Test std::unique_ptr pcap; std::unique_ptr du_metrics; std::unique_ptr f1ap_ue_id_mapper; - std::unique_ptr du_param_configurator; + std::unique_ptr du_param_configurator; std::unique_ptr e2_client; std::unique_ptr e2ap; srslog::basic_logger& test_logger = srslog::fetch_basic_logger("TEST"); diff --git a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_channel_emulator.cpp b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_channel_emulator.cpp index b34c04943d..936fb7e72d 100644 --- a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_channel_emulator.cpp +++ b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_channel_emulator.cpp @@ -31,10 +31,10 @@ unsigned channel_emulator::concurrent_channel_emulator::seed = 0; using tdl_tap = std::pair; /// Single-tap profile. -constexpr static std::array taps_single = {{{0, 0.0}}}; +static constexpr std::array taps_single = {{{0, 0.0}}}; /// TDLA fading profile. -constexpr static std::array taps_tdla = {{{0, -15.5}, +static constexpr std::array taps_tdla = {{{0, -15.5}, {10, 0.0}, {15, -5.1}, {20, -5.1}, @@ -48,7 +48,7 @@ constexpr static std::array taps_tdla = {{{0, -15.5}, {290, -26.2}}}; /// TDLB fading profile. -constexpr static std::array taps_tdlb = {{{0, 0}, +static constexpr std::array taps_tdlb = {{{0, 0}, {10, -2.2}, {20, -0.6}, {30, -0.6}, @@ -62,7 +62,7 @@ constexpr static std::array taps_tdlb = {{{0, 0}, {480, -7.1}}}; /// TDLC fading profile. -constexpr static std::array taps_tdlc = {{{0, -6.9}, +static constexpr std::array taps_tdlc = {{{0, -6.9}, {65, 0}, {70, -7.7}, {190, -2.5}, @@ -226,4 +226,4 @@ void channel_emulator::concurrent_channel_emulator::run(resource_grid_writer& // Write the OFDM symbol back to the grid. rx_grid.put(i_port, i_symbol, 0, temp_ofdm_symbol); -} \ No newline at end of file +} diff --git a/tests/test_doubles/scheduler/pucch_res_test_builder_helper.cpp b/tests/test_doubles/scheduler/pucch_res_test_builder_helper.cpp index e62cbe2c9a..b4da30b1e6 100644 --- a/tests/test_doubles/scheduler/pucch_res_test_builder_helper.cpp +++ b/tests/test_doubles/scheduler/pucch_res_test_builder_helper.cpp @@ -14,12 +14,12 @@ using namespace srsran; -static du_cell_config generate_du_cell_config(const bwp_uplink_common& init_ul_bwp, - std::optional tdd_ul_dl_cfg_common, - const serving_cell_config& base_ue_cfg, - const pucch_builder_params& pucch_cfg) +static srs_du::du_cell_config generate_du_cell_config(const bwp_uplink_common& init_ul_bwp, + std::optional tdd_ul_dl_cfg_common, + const serving_cell_config& base_ue_cfg, + const srs_du::pucch_builder_params& pucch_cfg) { - du_cell_config cell_cfg; + srs_du::du_cell_config cell_cfg; cell_cfg.ul_cfg_common.init_ul_bwp = init_ul_bwp; cell_cfg.tdd_ul_dl_cfg_common = tdd_ul_dl_cfg_common; cell_cfg.ue_ded_serv_cell_cfg = base_ue_cfg; @@ -32,15 +32,15 @@ pucch_res_builder_test_helper::pucch_res_builder_test_helper() : pucch_res_mgr(s pucch_res_builder_test_helper::pucch_res_builder_test_helper( const bwp_uplink_common& init_ul_bwp, std::optional tdd_ul_dl_cfg_common, - const pucch_builder_params& pucch_cfg) : + const srs_du::pucch_builder_params& pucch_cfg) : required_info(pucch_res_builder_info{.init_ul_bwp = init_ul_bwp, .tdd_ul_dl_cfg_common = tdd_ul_dl_cfg_common, .pucch_cfg = pucch_cfg}) { } -pucch_res_builder_test_helper::pucch_res_builder_test_helper(const cell_configuration& cell_cfg, - const pucch_builder_params& pucch_cfg) : +pucch_res_builder_test_helper::pucch_res_builder_test_helper(const cell_configuration& cell_cfg, + const srs_du::pucch_builder_params& pucch_cfg) : required_info(pucch_res_builder_info{.init_ul_bwp = cell_cfg.ul_cfg_common.init_ul_bwp, .tdd_ul_dl_cfg_common = cell_cfg.tdd_cfg_common, .pucch_cfg = pucch_cfg}) @@ -49,7 +49,7 @@ pucch_res_builder_test_helper::pucch_res_builder_test_helper(const cell_configur void pucch_res_builder_test_helper::setup(const bwp_uplink_common& init_ul_bwp_, std::optional tdd_ul_dl_cfg_common_, - const pucch_builder_params& pucch_cfg) + const srs_du::pucch_builder_params& pucch_cfg) { if (required_info.has_value()) { return; @@ -58,7 +58,8 @@ void pucch_res_builder_test_helper::setup(const bwp_uplink_common& .init_ul_bwp = init_ul_bwp_, .tdd_ul_dl_cfg_common = tdd_ul_dl_cfg_common_, .pucch_cfg = pucch_cfg}); } -void pucch_res_builder_test_helper::setup(const cell_configuration& cell_cfg, const pucch_builder_params& pucch_cfg) +void pucch_res_builder_test_helper::setup(const cell_configuration& cell_cfg, + const srs_du::pucch_builder_params& pucch_cfg) { setup(cell_cfg.ul_cfg_common.init_ul_bwp, cell_cfg.tdd_cfg_common, pucch_cfg); } @@ -91,9 +92,9 @@ void pucch_res_builder_test_helper::init_pucch_res_mgr(const serving_cell_config return; } pucch_res_mgr.emplace(srs_du::du_pucch_resource_manager( - static_vector{generate_du_cell_config(required_info.value().init_ul_bwp, - required_info.value().tdd_ul_dl_cfg_common, - base_ue_cfg, - required_info.value().pucch_cfg)}, + static_vector{generate_du_cell_config(required_info.value().init_ul_bwp, + required_info.value().tdd_ul_dl_cfg_common, + base_ue_cfg, + required_info.value().pucch_cfg)}, max_pucch_grants_per_slot)); } diff --git a/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h b/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h index b220617aab..757f1aed4b 100644 --- a/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h +++ b/tests/test_doubles/scheduler/pucch_res_test_builder_helper.h @@ -26,19 +26,19 @@ class pucch_res_builder_test_helper /// default constructor and then call \ref setup. explicit pucch_res_builder_test_helper(); - explicit pucch_res_builder_test_helper(const cell_configuration& cell_cfg, - const pucch_builder_params& pucch_cfg = {}); + explicit pucch_res_builder_test_helper(const cell_configuration& cell_cfg, + const srs_du::pucch_builder_params& pucch_cfg = {}); explicit pucch_res_builder_test_helper(const bwp_uplink_common& init_ul_bwp, std::optional tdd_ul_dl_cfg_common, - const pucch_builder_params& pucch_cfg = {}); + const srs_du::pucch_builder_params& pucch_cfg = {}); /// Initializes the variables after this class has been constructed with default ctor. /// \remark This function won't do anything if the class was constructed with the non-default constructor. void setup(const bwp_uplink_common& init_ul_bwp, std::optional tdd_ul_dl_cfg_common, - const pucch_builder_params& pucch_cfg = {}); - void setup(const cell_configuration& cell_cfg, const pucch_builder_params& pucch_cfg = {}); + const srs_du::pucch_builder_params& pucch_cfg = {}); + void setup(const cell_configuration& cell_cfg, const srs_du::pucch_builder_params& pucch_cfg = {}); /// Build a new UE's PUCCH config (embedded in \ref serving_cell_config) and add this to the /// \ref du_pucch_resource_manager to keep track of which cell PUCCH resources have been used. @@ -52,12 +52,12 @@ class pucch_res_builder_test_helper struct pucch_res_builder_info { const bwp_uplink_common init_ul_bwp; std::optional tdd_ul_dl_cfg_common; - pucch_builder_params pucch_cfg; + srs_du::pucch_builder_params pucch_cfg; }; std::optional required_info; std::optional pucch_res_mgr; - constexpr static unsigned max_pucch_grants_per_slot = 64; + static constexpr unsigned max_pucch_grants_per_slot = 64; }; } // namespace srsran diff --git a/tests/unittests/adt/byte_buffer_test.cpp b/tests/unittests/adt/byte_buffer_test.cpp index 13ec22b4ce..c360acbc2e 100644 --- a/tests/unittests/adt/byte_buffer_test.cpp +++ b/tests/unittests/adt/byte_buffer_test.cpp @@ -785,7 +785,7 @@ TEST_F(byte_buffer_tester, append_rvalue_byte_buffer) TEST_P(byte_buffer_stress_tester, concurrent_alloc_dealloc_test) { - const static unsigned MAX_COUNT = 100000; + static const unsigned MAX_COUNT = 100000; const unsigned NOF_THREADS = 4; std::mutex mutex; std::condition_variable cvar; diff --git a/tests/unittests/cu_up/cu_up_test_helpers.h b/tests/unittests/cu_up/cu_up_test_helpers.h index e22beb77ea..25f577d4c6 100644 --- a/tests/unittests/cu_up/cu_up_test_helpers.h +++ b/tests/unittests/cu_up/cu_up_test_helpers.h @@ -257,7 +257,7 @@ class dummy_e1ap final : public srs_cu_up::e1ap_control_message_handler } }; -inline e1ap_message generate_bearer_context_setup_request(unsigned int cu_cp_ue_e1ap_id) +inline e1ap_message generate_bearer_context_setup_request(unsigned cu_cp_ue_e1ap_id) { e1ap_message bearer_context_setup_request = {}; diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index 70aa8b0935..fb8865308d 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -327,7 +327,7 @@ static du_cell_config make_custom_du_cell_config(const pucch_cfg_builder_params& pucch_params.nof_csi_resources = pucch_params_.nof_res_csi; pucch_params.nof_cell_harq_pucch_res_sets = pucch_params_.nof_harq_cfg; auto& f1_params = std::get(pucch_params.f0_or_f1_params); - f1_params.nof_cyc_shifts = srsran::nof_cyclic_shifts::six; + f1_params.nof_cyc_shifts = nof_cyclic_shifts::six; f1_params.occ_supported = true; return du_cfg; @@ -581,15 +581,15 @@ INSTANTIATE_TEST_SUITE_P(different_f1_f2_resources, ); static du_cell_config -make_custom_du_cell_config_for_pucch_cnt(const pucch_cnt_builder_params& pucch_params_, - const srsran::config_helpers::cell_config_builder_params_extended& params = {}) +make_custom_du_cell_config_for_pucch_cnt(const pucch_cnt_builder_params& pucch_params_, + const config_helpers::cell_config_builder_params_extended& params = {}) { du_cell_config du_cfg = config_helpers::make_default_du_cell_config(params); auto& pucch_params = du_cfg.pucch_cfg; pucch_params.nof_sr_resources = pucch_params_.nof_res_sr; pucch_params.nof_csi_resources = pucch_params_.nof_res_csi; auto& f1_params = std::get(pucch_params.f0_or_f1_params); - f1_params.nof_cyc_shifts = srsran::nof_cyclic_shifts::six; + f1_params.nof_cyc_shifts = nof_cyclic_shifts::six; f1_params.occ_supported = true; du_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.pucch_cfg->sr_res_list[0].period = pucch_params_.sr_period; diff --git a/tests/unittests/du_manager/procedures/ue_configuration_test.cpp b/tests/unittests/du_manager/procedures/ue_configuration_test.cpp index 765c370233..ca44ba02da 100644 --- a/tests/unittests/du_manager/procedures/ue_configuration_test.cpp +++ b/tests/unittests/du_manager/procedures/ue_configuration_test.cpp @@ -234,7 +234,7 @@ TEST_F(ue_config_tester, when_du_manager_completes_ue_configuration_procedure_th TEST_F(ue_config_tester, when_du_manager_finishes_processing_ue_config_request_then_mac_rlc_f1c_bearers_are_connected) { - const static std::array dummy_rlc_header = {0x80, 0x0}; + static const std::array dummy_rlc_header = {0x80, 0x0}; byte_buffer test_payload = test_helpers::create_pdcp_pdu( pdcp_sn_size::size12bits, /* is_srb = */ true, 0, test_rgen::uniform_int(3, 100), 0); @@ -267,7 +267,7 @@ TEST_F(ue_config_tester, when_du_manager_finishes_processing_ue_config_request_t TEST_F(ue_config_tester, when_du_manager_finishes_processing_ue_config_request_then_mac_rlc_f1u_bearers_are_connected) { - const static std::array dummy_rlc_header = {0x80, 0x0}; + static const std::array dummy_rlc_header = {0x80, 0x0}; byte_buffer test_payload = test_helpers::create_pdcp_pdu( pdcp_sn_size::size12bits, /* is_srb = */ false, 0, test_rgen::uniform_int(3, 100), 0); @@ -308,7 +308,7 @@ TEST_F(ue_config_tester, std::string f1u_ext_addr = "5.6.7.8"; f1u_gw.set_f1u_ext_addr(f1u_ext_addr); - const static std::array dummy_rlc_header = {0x80, 0x0}; + static const std::array dummy_rlc_header = {0x80, 0x0}; byte_buffer test_payload = test_helpers::create_pdcp_pdu( pdcp_sn_size::size12bits, /* is_srb = */ false, 0, test_rgen::uniform_int(3, 100), 0); diff --git a/tests/unittests/du_manager/sib_test.cpp b/tests/unittests/du_manager/sib_test.cpp index 7052c938c6..0246440434 100644 --- a/tests/unittests/du_manager/sib_test.cpp +++ b/tests/unittests/du_manager/sib_test.cpp @@ -14,10 +14,11 @@ #include #include +using namespace srsran; +using namespace srs_du; + TEST(srs_sib19_test, make_asn1_rrc_cell_sib19_buffer) { - using namespace srsran; - sib19_info sib19; sib19.cell_specific_koffset.emplace(); sib19.cell_specific_koffset.value() = 260; @@ -30,7 +31,7 @@ TEST(srs_sib19_test, make_asn1_rrc_cell_sib19_buffer) std::get(sib19.ephemeris_info.value()).velocity_vz = 6; // Call the function being tested std::string js_str; - auto buf = srsran::srs_du::make_asn1_rrc_cell_sib19_buffer(sib19, &js_str); + auto buf = make_asn1_rrc_cell_sib19_buffer(sib19, &js_str); // Check that the buffer is not empty EXPECT_FALSE(buf.empty()); diff --git a/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.cpp b/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.cpp index 32ff369422..342acfc27b 100644 --- a/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.cpp +++ b/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.cpp @@ -41,7 +41,7 @@ e1ap_message srsran::srs_cu_up::generate_cu_up_e1_setup_response(unsigned transa return e1_setup_response; } -e1ap_message srsran::srs_cu_up::generate_bearer_context_setup_request(unsigned int cu_cp_ue_e1ap_id) +e1ap_message srsran::srs_cu_up::generate_bearer_context_setup_request(unsigned cu_cp_ue_e1ap_id) { e1ap_message bearer_context_setup_request = {}; @@ -123,7 +123,7 @@ e1ap_message srsran::srs_cu_up::generate_bearer_context_setup_request(unsigned i return bearer_context_setup_request; } -e1ap_message srsran::srs_cu_up::generate_invalid_bearer_context_setup_request(unsigned int cu_cp_ue_e1ap_id) +e1ap_message srsran::srs_cu_up::generate_invalid_bearer_context_setup_request(unsigned cu_cp_ue_e1ap_id) { e1ap_message bearer_context_setup_request = {}; @@ -145,7 +145,7 @@ e1ap_message srsran::srs_cu_up::generate_invalid_bearer_context_setup_request(un } e1ap_message -srsran::srs_cu_up::generate_invalid_bearer_context_setup_request_inactivity_timer(unsigned int cu_cp_ue_e1ap_id) +srsran::srs_cu_up::generate_invalid_bearer_context_setup_request_inactivity_timer(unsigned cu_cp_ue_e1ap_id) { e1ap_message bearer_context_setup_request = {}; bearer_context_setup_request = generate_bearer_context_setup_request(cu_cp_ue_e1ap_id); @@ -155,8 +155,8 @@ srsran::srs_cu_up::generate_invalid_bearer_context_setup_request_inactivity_time return bearer_context_setup_request; } -e1ap_message srsran::srs_cu_up::generate_bearer_context_modification_request(unsigned int cu_cp_ue_e1ap_id, - unsigned int cu_up_ue_e1ap_id) +e1ap_message srsran::srs_cu_up::generate_bearer_context_modification_request(unsigned cu_cp_ue_e1ap_id, + unsigned cu_up_ue_e1ap_id) { e1ap_message bearer_context_modification_request = {}; @@ -193,8 +193,8 @@ e1ap_message srsran::srs_cu_up::generate_bearer_context_modification_request(uns return bearer_context_modification_request; } -e1ap_message srsran::srs_cu_up::generate_invalid_bearer_context_modification_request(unsigned int cu_cp_ue_e1ap_id, - unsigned int cu_up_ue_e1ap_id) +e1ap_message srsran::srs_cu_up::generate_invalid_bearer_context_modification_request(unsigned cu_cp_ue_e1ap_id, + unsigned cu_up_ue_e1ap_id) { e1ap_message bearer_context_modification_request = {}; @@ -211,8 +211,8 @@ e1ap_message srsran::srs_cu_up::generate_invalid_bearer_context_modification_req return bearer_context_modification_request; } -e1ap_message srsran::srs_cu_up::generate_bearer_context_release_command(unsigned int cu_cp_ue_e1ap_id, - unsigned int cu_up_ue_e1ap_id) +e1ap_message srsran::srs_cu_up::generate_bearer_context_release_command(unsigned cu_cp_ue_e1ap_id, + unsigned cu_up_ue_e1ap_id) { e1ap_message bearer_context_release_command = {}; diff --git a/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.h b/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.h index c32cd4b628..9754d8700d 100644 --- a/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.h +++ b/tests/unittests/e1ap/common/e1ap_cu_up_test_messages.h @@ -22,23 +22,22 @@ cu_up_e1_setup_request generate_cu_up_e1_setup_request(); e1ap_message generate_cu_up_e1_setup_response(unsigned transaction_id); /// \brief Generate a dummy bearer context setup request. -e1ap_message generate_bearer_context_setup_request(unsigned int cu_cp_ue_e1ap_id); +e1ap_message generate_bearer_context_setup_request(unsigned cu_cp_ue_e1ap_id); /// \brief Generate an invalid dummy bearer context setup request. -e1ap_message generate_invalid_bearer_context_setup_request(unsigned int cu_cp_ue_e1ap_id); +e1ap_message generate_invalid_bearer_context_setup_request(unsigned cu_cp_ue_e1ap_id); /// \brief Generate a dummy bearer context setup request, with an invalid inactivity timer. -e1ap_message generate_invalid_bearer_context_setup_request_inactivity_timer(unsigned int cu_cp_ue_e1ap_id); +e1ap_message generate_invalid_bearer_context_setup_request_inactivity_timer(unsigned cu_cp_ue_e1ap_id); /// \brief Generate a dummy bearer context modification request. -e1ap_message generate_bearer_context_modification_request(unsigned int cu_cp_ue_e1ap_id, unsigned int cu_up_ue_e1ap_id); +e1ap_message generate_bearer_context_modification_request(unsigned cu_cp_ue_e1ap_id, unsigned cu_up_ue_e1ap_id); /// \brief Generate an invalid dummy bearer context modification request. -e1ap_message generate_invalid_bearer_context_modification_request(unsigned int cu_cp_ue_e1ap_id, - unsigned int cu_up_ue_e1ap_id); +e1ap_message generate_invalid_bearer_context_modification_request(unsigned cu_cp_ue_e1ap_id, unsigned cu_up_ue_e1ap_id); /// \brief Generate a dummy bearer context release command. -e1ap_message generate_bearer_context_release_command(unsigned int cu_cp_ue_e1ap_id, unsigned int cu_up_ue_e1ap_id); +e1ap_message generate_bearer_context_release_command(unsigned cu_cp_ue_e1ap_id, unsigned cu_up_ue_e1ap_id); } // namespace srs_cu_up } // namespace srsran diff --git a/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.cpp b/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.cpp index 5d02793b82..66c51b8da8 100644 --- a/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.cpp +++ b/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.cpp @@ -72,7 +72,7 @@ e1ap_cu_up_test::~e1ap_cu_up_test() srslog::flush(); } -void e1ap_cu_up_test::setup_bearer(unsigned int cu_cp_ue_e1ap_id) +void e1ap_cu_up_test::setup_bearer(unsigned cu_cp_ue_e1ap_id) { // Generate BearerContextSetupRequest e1ap_message bearer_context_setup = generate_bearer_context_setup_request(cu_cp_ue_e1ap_id); diff --git a/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.h b/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.h index 4d3ccb9c7f..4afc35f9ad 100644 --- a/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.h +++ b/tests/unittests/e1ap/cu_up/e1ap_cu_up_test_helpers.h @@ -44,7 +44,7 @@ class e1ap_cu_up_test : public ::testing::Test void run_e1_setup_procedure(); /// \brief Helper method to setup a bearer at the CU-UP - void setup_bearer(unsigned int cu_cp_ue_e1ap_id); + void setup_bearer(unsigned cu_cp_ue_e1ap_id); /// Dummy E1AP gateway to connect to CU-CP and send E1AP PDUs. dummy_e1_connection_client e1ap_gw; diff --git a/tests/unittests/e2/common/e2_test_helpers.h b/tests/unittests/e2/common/e2_test_helpers.h index ec93ab1f30..050d5f7c77 100644 --- a/tests/unittests/e2/common/e2_test_helpers.h +++ b/tests/unittests/e2/common/e2_test_helpers.h @@ -758,18 +758,18 @@ class dummy_e2_connection_client final : public e2_connection_client dummy_e2_pdu_notifier* msg_notifier; }; -class dummy_du_configurator : public du_configurator +class dummy_du_configurator : public srs_du::du_configurator { public: dummy_du_configurator(){}; - async_task - configure_ue_mac_scheduler(du_mac_sched_control_config reconf) override + async_task + configure_ue_mac_scheduler(srs_du::du_mac_sched_control_config reconf) override { - du_mac_sched_control_config config; + srs_du::du_mac_sched_control_config config; config = reconf; - return launch_async([](coro_context>& ctx) { + return launch_async([](coro_context>& ctx) { CORO_BEGIN(ctx); - CORO_RETURN(du_mac_sched_control_config_response{true, true, true}); + CORO_RETURN(srs_du::du_mac_sched_control_config_response{true, true, true}); }); } }; @@ -796,7 +796,7 @@ class e2_base std::unique_ptr rc_control_action_2_6_executor; std::unique_ptr e2sm_kpm_packer; std::unique_ptr e2sm_rc_packer; - std::unique_ptr rc_param_configurator; + std::unique_ptr rc_param_configurator; std::unique_ptr e2_subscription_mngr; std::unique_ptr du_metrics; std::unique_ptr f1ap_ue_id_mapper; @@ -847,7 +847,7 @@ class e2_external_test : public e2_test_base srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; msg_notifier = std::make_unique(nullptr); @@ -880,7 +880,7 @@ class e2_entity_test : public e2_test_base srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; gw = std::make_unique(); @@ -908,7 +908,7 @@ class e2_test_subscriber : public e2_test_base { srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; factory = timer_factory{timers, task_worker}; @@ -940,7 +940,7 @@ class e2_test_setup : public e2_test_base { void SetUp() override { - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; factory = timer_factory{timers, task_worker}; diff --git a/tests/unittests/e2/e2ap_network_adapter_test.cpp b/tests/unittests/e2/e2ap_network_adapter_test.cpp index fb20b13da8..9e2e99378f 100644 --- a/tests/unittests/e2/e2ap_network_adapter_test.cpp +++ b/tests/unittests/e2/e2ap_network_adapter_test.cpp @@ -69,7 +69,7 @@ class e2ap_network_adapter_test : public ::testing::Test e2agent_config.bind_address = "127.0.0.101"; e2agent_config.bind_port = 0; - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; pcap = std::make_unique(); diff --git a/tests/unittests/e2/e2sm_kpm_meas_provider_test.cpp b/tests/unittests/e2/e2sm_kpm_meas_provider_test.cpp index a2437ee7fd..1d8e1be3f2 100644 --- a/tests/unittests/e2/e2sm_kpm_meas_provider_test.cpp +++ b/tests/unittests/e2/e2sm_kpm_meas_provider_test.cpp @@ -65,7 +65,7 @@ class e2sm_kpm_meas_provider_test : public ::testing::Test srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; du_metrics = std::make_unique(); diff --git a/tests/unittests/e2/e2sm_kpm_test.cpp b/tests/unittests/e2/e2sm_kpm_test.cpp index 4f11a12b55..cc2468241f 100644 --- a/tests/unittests/e2/e2sm_kpm_test.cpp +++ b/tests/unittests/e2/e2sm_kpm_test.cpp @@ -37,7 +37,7 @@ class e2_entity_test_with_pcap : public e2_test_base_with_pcap srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; gw = std::make_unique(); @@ -76,7 +76,7 @@ class e2sm_kpm_indication : public e2_test_base_with_pcap srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - cfg = srsran::config_helpers::make_default_e2ap_config(); + cfg = config_helpers::make_default_e2ap_config(); cfg.e2sm_kpm_enabled = true; du_metrics = std::make_unique(); diff --git a/tests/unittests/f1u/common/f1u_connector_test.cpp b/tests/unittests/f1u/common/f1u_connector_test.cpp index bf55542ae0..4ba7c694a6 100644 --- a/tests/unittests/f1u/common/f1u_connector_test.cpp +++ b/tests/unittests/f1u/common/f1u_connector_test.cpp @@ -29,7 +29,7 @@ struct dummy_f1u_cu_up_rx_notifier final : public f1u_cu_up_gateway_bearer_rx_no srslog::basic_logger& logger = srslog::fetch_basic_logger("CU-F1-U", false); }; -struct dummy_f1u_du_gateway_bearer_rx_notifier final : srsran::srs_du::f1u_du_gateway_bearer_rx_notifier { +struct dummy_f1u_du_gateway_bearer_rx_notifier final : srs_du::f1u_du_gateway_bearer_rx_notifier { void on_new_pdu(nru_dl_message msg) override { logger.info(msg.t_pdu.begin(), msg.t_pdu.end(), "DU received SDU. sdu_len={}", msg.t_pdu.length()); diff --git a/tests/unittests/f1u/common/f1u_du_split_connector_test.cpp b/tests/unittests/f1u/common/f1u_du_split_connector_test.cpp index b03445eb98..061e5a890a 100644 --- a/tests/unittests/f1u/common/f1u_du_split_connector_test.cpp +++ b/tests/unittests/f1u/common/f1u_du_split_connector_test.cpp @@ -22,7 +22,7 @@ using namespace srs_du; namespace { -struct dummy_f1u_du_gateway_bearer_rx_notifier final : srsran::srs_du::f1u_du_gateway_bearer_rx_notifier { +struct dummy_f1u_du_gateway_bearer_rx_notifier final : f1u_du_gateway_bearer_rx_notifier { void on_new_pdu(nru_dl_message msg) override { logger.info(msg.t_pdu.begin(), msg.t_pdu.end(), "DU received SDU. sdu_len={}", msg.t_pdu.length()); diff --git a/tests/unittests/gateways/sctp_test_helpers.h b/tests/unittests/gateways/sctp_test_helpers.h index 0a74772f3f..43a635c0eb 100644 --- a/tests/unittests/gateways/sctp_test_helpers.h +++ b/tests/unittests/gateways/sctp_test_helpers.h @@ -97,7 +97,7 @@ class dummy_sctp_node std::optional receive() { - constexpr static uint32_t network_gateway_sctp_max_len = 9100; + static constexpr uint32_t network_gateway_sctp_max_len = 9100; test_recv_data data; diff --git a/tests/unittests/mac/mac_ctrl_test_dummies.h b/tests/unittests/mac/mac_ctrl_test_dummies.h index fb32f57189..73777cda2a 100644 --- a/tests/unittests/mac/mac_ctrl_test_dummies.h +++ b/tests/unittests/mac/mac_ctrl_test_dummies.h @@ -85,7 +85,7 @@ class mac_dl_dummy_configurer final : public mac_dl_configurator mac_cell_controller& get_cell_controller(du_cell_index_t cell_index) override { return cell_ctrl; } }; -class dummy_ue_executor_mapper : public du_high_ue_executor_mapper +class dummy_ue_executor_mapper : public srs_du::du_high_ue_executor_mapper { public: dummy_ue_executor_mapper(task_executor& exec_) : exec(exec_) {} @@ -98,7 +98,7 @@ class dummy_ue_executor_mapper : public du_high_ue_executor_mapper task_executor& exec; }; -class dummy_dl_executor_mapper : public du_high_cell_executor_mapper +class dummy_dl_executor_mapper : public srs_du::du_high_cell_executor_mapper { public: dummy_dl_executor_mapper(const std::initializer_list& execs_) : execs(execs_.begin(), execs_.end()) {} diff --git a/tests/unittests/mac/mac_rar_pdu_assembler_test.cpp b/tests/unittests/mac/mac_rar_pdu_assembler_test.cpp index 3cbc76b2d4..b92b59c0dd 100644 --- a/tests/unittests/mac/mac_rar_pdu_assembler_test.cpp +++ b/tests/unittests/mac/mac_rar_pdu_assembler_test.cpp @@ -127,7 +127,7 @@ void test_encoded_rar(const rar_information& original_rar, span r TEST(rar_assembler_test, multiple_random_ul_grants) { - constexpr static size_t MAX_RAR_GRANT_SIZE = 64; + static constexpr size_t MAX_RAR_GRANT_SIZE = 64; test_delimit_logger test_delim{"MAC assembler for multiple UL grants"}; rar_information rar_info = make_random_rar_info(nof_ul_grants_per_rar(gen)); @@ -143,7 +143,7 @@ TEST(rar_assembler_test, multiple_random_ul_grants) /// so that the output PDUs can be referenced by lower layers without risking dangling pointers. TEST(rar_assembler_test, rar_assembler_maintains_old_results) { - constexpr static size_t MAX_RAR_GRANT_SIZE = 64; + static constexpr size_t MAX_RAR_GRANT_SIZE = 64; test_delimit_logger test_delim{"MAC assembler maintains previous results"}; diff --git a/tests/unittests/ngap/ngap_test_messages.h b/tests/unittests/ngap/ngap_test_messages.h index fea48188ef..df83af01d7 100644 --- a/tests/unittests/ngap/ngap_test_messages.h +++ b/tests/unittests/ngap/ngap_test_messages.h @@ -79,7 +79,7 @@ bool is_pdu_type(const ngap_message& pdu, const asn1::ngap::ngap_elem_procs_o::s // criticality: ignore (1) // value // PagingDRX: v256 (3) -const static uint8_t ng_setup_request_packed[] = { +static const uint8_t ng_setup_request_packed[] = { 0x00, 0x15, 0x00, 0x33, 0x00, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x08, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x06, 0x6c, 0x00, 0x52, 0x40, 0x0a, 0x03, 0x80, 0x73, 0x72, 0x73, 0x67, 0x6e, 0x62, 0x30, 0x31, 0x00, 0x66, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x15, 0x40, 0x01, 0x60}; diff --git a/tests/unittests/rlc/rlc_rx_am_test.cpp b/tests/unittests/rlc/rlc_rx_am_test.cpp index dcc867bc9b..97fff259fe 100644 --- a/tests/unittests/rlc/rlc_rx_am_test.cpp +++ b/tests/unittests/rlc/rlc_rx_am_test.cpp @@ -1428,7 +1428,7 @@ TEST_P(rlc_rx_am_test, rx_reverse_with_reversed_segmentation) std::string test_param_info_to_string(const ::testing::TestParamInfo& info) { - constexpr static const char* options[] = {"12bit", "18bit"}; + static constexpr const char* options[] = {"12bit", "18bit"}; return options[info.index]; } @@ -1439,7 +1439,7 @@ INSTANTIATE_TEST_SUITE_P(rlc_rx_am_test_each_sn_size, std::string test_param_info_to_string_status_limit(const ::testing::TestParamInfo& info) { - constexpr static const char* options[] = {"12bit", "18bit", "12bit_status_limit", "18bit_status_limit"}; + static constexpr const char* options[] = {"12bit", "18bit", "12bit_status_limit", "18bit_status_limit"}; return options[info.index]; } diff --git a/tests/unittests/scheduler/cell/cell_harq_manager_test.cpp b/tests/unittests/scheduler/cell/cell_harq_manager_test.cpp index 0a8f6a150e..8a199ef57e 100644 --- a/tests/unittests/scheduler/cell/cell_harq_manager_test.cpp +++ b/tests/unittests/scheduler/cell/cell_harq_manager_test.cpp @@ -140,7 +140,7 @@ class multi_ue_harq_manager_test : public base_harq_manager_test, public ::testi protected: multi_ue_harq_manager_test() : base_harq_manager_test(max_ues) {} - constexpr static unsigned max_ues = 4; + static constexpr unsigned max_ues = 4; const unsigned nof_harqs = 8; }; @@ -1088,4 +1088,4 @@ TEST_F(single_ntn_ue_harq_process_test, when_harq_gets_acked_then_it_reports_the ASSERT_EQ(h_dl.dl_ack_info(mac_harq_ack_report_status::ack, std::nullopt), dl_harq_process_handle::status_update::acked); ASSERT_EQ(h_dl.get_grant_params().tbs_bytes, pdsch_info.codewords[0].tb_size_bytes); -} \ No newline at end of file +} diff --git a/tests/unittests/scheduler/multiple_ue_sched_test.cpp b/tests/unittests/scheduler/multiple_ue_sched_test.cpp index 2c5df389f0..4dd4a2f042 100644 --- a/tests/unittests/scheduler/multiple_ue_sched_test.cpp +++ b/tests/unittests/scheduler/multiple_ue_sched_test.cpp @@ -118,13 +118,13 @@ class scheduler_impl_tester test_logger.set_context(current_slot.sfn(), current_slot.slot_index()); bench->sched_res = &bench->sch.slot_indication(current_slot, to_du_cell_index(0)); - pucch_builder_params pucch_basic_params{.nof_ue_pucch_f0_or_f1_res_harq = 8, - .nof_ue_pucch_f2_res_harq = 8, - .nof_sr_resources = 8, - .nof_csi_resources = 8}; - auto& f1_params = pucch_basic_params.f0_or_f1_params.emplace(); - f1_params.nof_cyc_shifts = srsran::nof_cyclic_shifts::twelve; - f1_params.occ_supported = true; + srs_du::pucch_builder_params pucch_basic_params{.nof_ue_pucch_f0_or_f1_res_harq = 8, + .nof_ue_pucch_f2_res_harq = 8, + .nof_sr_resources = 8, + .nof_csi_resources = 8}; + auto& f1_params = pucch_basic_params.f0_or_f1_params.emplace(); + f1_params.nof_cyc_shifts = srs_du::nof_cyclic_shifts::twelve; + f1_params.occ_supported = true; pucch_cfg_builder.setup(bench->cell_cfg, pucch_basic_params); } diff --git a/tests/unittests/scheduler/scheduler_ue_fallback_mode_test.cpp b/tests/unittests/scheduler/scheduler_ue_fallback_mode_test.cpp index 0bb860b8d3..daf141816c 100644 --- a/tests/unittests/scheduler/scheduler_ue_fallback_mode_test.cpp +++ b/tests/unittests/scheduler/scheduler_ue_fallback_mode_test.cpp @@ -124,7 +124,7 @@ class scheduler_con_res_msg4_test : public base_scheduler_conres_test, TEST_P(scheduler_con_res_msg4_test, when_conres_ce_and_srb_pdu_are_enqueued_then_tc_rnti_is_used_and_multiplexing_with_csi_rs_is_avoided) { - const static unsigned msg4_size = 128; + static const unsigned msg4_size = 128; // Enqueue several RACH indications, so that RARs that need to be scheduled may fight for RB space with the Msg4. enqueue_random_number_of_rach_indications(); @@ -162,10 +162,10 @@ TEST_P(scheduler_con_res_msg4_test, TEST_P(scheduler_con_res_msg4_test, while_ue_is_in_fallback_then_common_pucch_is_used) { - const static unsigned msg4_size = 128; + static const unsigned msg4_size = 128; // TODO: Increase the crnti message size, once PUCCH scheduler handles multiple HARQ-ACKs falling in the same slot // in fallback mode. - const static unsigned crnti_msg_size = 8; + static const unsigned crnti_msg_size = 8; // Enqueue ConRes CE + Msg4. this->sched->handle_dl_mac_ce_indication(dl_mac_ce_indication{ue_index, lcid_dl_sch_t::UE_CON_RES_ID}); @@ -268,7 +268,7 @@ TEST_P(scheduler_con_res_msg4_test, while_ue_is_in_fallback_then_common_pucch_is TEST_P(scheduler_con_res_msg4_test, while_ue_is_in_fallback_then_common_ss_is_used) { - const static unsigned msg4_size = 128; + static const unsigned msg4_size = 128; // Enqueue ConRes CE + Msg4. this->sched->handle_dl_mac_ce_indication(dl_mac_ce_indication{ue_index, lcid_dl_sch_t::UE_CON_RES_ID}); diff --git a/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp b/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp index aabb0b4b9c..7d317987bd 100644 --- a/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp +++ b/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp @@ -171,13 +171,13 @@ TEST_F(default_slice_scheduler_test, when_grant_gets_allocated_then_number_of_av TEST_F(default_slice_scheduler_test, returns_only_dl_pending_bytes_of_bearers_belonging_to_a_slice) { - constexpr static ran_slice_id_t default_srb_slice_id{0}; - constexpr static ran_slice_id_t default_drb_slice_id{1}; + static constexpr ran_slice_id_t default_srb_slice_id{0}; + static constexpr ran_slice_id_t default_drb_slice_id{1}; - constexpr static unsigned srb_pending_bytes{200}; - constexpr static unsigned drb_pending_bytes{5000}; + static constexpr unsigned srb_pending_bytes{200}; + static constexpr unsigned drb_pending_bytes{5000}; - constexpr static du_ue_index_t ue_idx{to_du_ue_index(0)}; + static constexpr du_ue_index_t ue_idx{to_du_ue_index(0)}; ASSERT_NE(this->add_ue(ue_idx), nullptr); // Push buffer state indication for DRB. @@ -209,18 +209,18 @@ TEST_F(default_slice_scheduler_test, returns_only_dl_pending_bytes_of_bearers_be TEST_F(default_slice_scheduler_test, returns_only_ul_pending_bytes_of_bearers_belonging_to_a_slice) { // Estimate of the number of bytes required for the upper layer header. - constexpr static unsigned RLC_HEADER_SIZE_ESTIMATE = 3U; + static constexpr unsigned RLC_HEADER_SIZE_ESTIMATE = 3U; - constexpr static ran_slice_id_t default_srb_slice_id{0}; - constexpr static ran_slice_id_t default_drb_slice_id{1}; + static constexpr ran_slice_id_t default_srb_slice_id{0}; + static constexpr ran_slice_id_t default_drb_slice_id{1}; - constexpr static unsigned srb_pending_bytes{200}; - constexpr static unsigned drb_pending_bytes{5000}; + static constexpr unsigned srb_pending_bytes{200}; + static constexpr unsigned drb_pending_bytes{5000}; const lcg_id_t srb_lcg_id = config_helpers::create_default_logical_channel_config(lcid_t::LCID_SRB1).lc_group; const lcg_id_t drb_lcg_id = config_helpers::create_default_logical_channel_config(lcid_t::LCID_MIN_DRB).lc_group; - constexpr static du_ue_index_t ue_idx{to_du_ue_index(0)}; + static constexpr du_ue_index_t ue_idx{to_du_ue_index(0)}; ASSERT_NE(this->add_ue(ue_idx), nullptr); // Push UL BSR for DRB. @@ -259,13 +259,13 @@ TEST_F(default_slice_scheduler_test, returns_only_ul_pending_bytes_of_bearers_be class rb_ratio_slice_scheduler_test : public slice_scheduler_test, public ::testing::Test { protected: - constexpr static unsigned MIN_SLICE_RB = 10; - constexpr static unsigned MAX_SLICE_RB = 20; + static constexpr unsigned MIN_SLICE_RB = 10; + static constexpr unsigned MAX_SLICE_RB = 20; - constexpr static ran_slice_id_t default_srb_slice_id{0}; - constexpr static ran_slice_id_t default_drb_slice_id{1}; - constexpr static ran_slice_id_t drb1_slice_id{2}; - constexpr static ran_slice_id_t drb2_slice_id{3}; + static constexpr ran_slice_id_t default_srb_slice_id{0}; + static constexpr ran_slice_id_t default_drb_slice_id{1}; + static constexpr ran_slice_id_t drb1_slice_id{2}; + static constexpr ran_slice_id_t drb2_slice_id{3}; rb_ratio_slice_scheduler_test() : slice_scheduler_test({{{plmn_identity::test_value(), s_nssai_t{1}}, MIN_SLICE_RB, MAX_SLICE_RB}, diff --git a/tests/unittests/scheduler/test_doubles/test_pucch_res_test_builder_helper.cpp b/tests/unittests/scheduler/test_doubles/test_pucch_res_test_builder_helper.cpp index cd0abb5ca7..1bda35e95d 100644 --- a/tests/unittests/scheduler/test_doubles/test_pucch_res_test_builder_helper.cpp +++ b/tests/unittests/scheduler/test_doubles/test_pucch_res_test_builder_helper.cpp @@ -46,7 +46,7 @@ class sched_pucch_res_builder_tester : public ::testing::TestWithParam cell_configuration cell_cfg; cell_config_dedicated cell_cfg_dedicated; - pucch_builder_params pucch_params; + srs_du::pucch_builder_params pucch_params; std::vector ues; unsigned ue_cnt = 0; pucch_res_builder_test_helper pucch_builder; diff --git a/tests/unittests/scheduler/test_utils/config_generators.h b/tests/unittests/scheduler/test_utils/config_generators.h index 4027570ceb..d9c5211a3b 100644 --- a/tests/unittests/scheduler/test_utils/config_generators.h +++ b/tests/unittests/scheduler/test_utils/config_generators.h @@ -53,7 +53,7 @@ make_default_sched_cell_configuration_request(const config_helpers::cell_config_ sched_req.searchspace0 = params.search_space0_index; sched_req.sib1_payload_size = 101; // Random size. - pucch_builder_params default_pucch_builder_params = du_cell_config{}.pucch_cfg; + srs_du::pucch_builder_params default_pucch_builder_params = srs_du::du_cell_config{}.pucch_cfg; default_pucch_builder_params.nof_ue_pucch_f0_or_f1_res_harq = 3; default_pucch_builder_params.nof_ue_pucch_f2_res_harq = 6; default_pucch_builder_params.nof_sr_resources = 2; diff --git a/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp b/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp index a8c33137df..47d66dd4d8 100644 --- a/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp +++ b/tests/unittests/scheduler/uci_and_pucch/pucch_res_manager_test.cpp @@ -612,8 +612,8 @@ class test_pucch_res_manager_multiple_cfg : public test_pucch_resource_manager cell_pucch_res_list = srs_du::generate_cell_pucch_res_list((nof_res_per_ue + 1) * nof_configurations, (nof_res_per_ue + 1) * nof_configurations, - pucch_f1_params{}, - pucch_f2_params{}, + srs_du::pucch_f1_params{}, + srs_du::pucch_f2_params{}, cell_cfg.dl_cfg_common.init_dl_bwp.generic_params.crbs.length(), NOF_OFDM_SYM_PER_SLOT_NORMAL_CP); for (unsigned ue_idx = 0; ue_idx != nof_ues; ++ue_idx) { diff --git a/tests/unittests/scheduler/uci_and_pucch/scheduler_uci_indication_test.cpp b/tests/unittests/scheduler/uci_and_pucch/scheduler_uci_indication_test.cpp index 0835064d94..e8531c6fff 100644 --- a/tests/unittests/scheduler/uci_and_pucch/scheduler_uci_indication_test.cpp +++ b/tests/unittests/scheduler/uci_and_pucch/scheduler_uci_indication_test.cpp @@ -129,8 +129,8 @@ class uci_sched_tester : public ::testing::Test }); } - constexpr static du_ue_index_t ue_id = to_du_ue_index(0); - constexpr static rnti_t ue_rnti = to_rnti(0x4601); + static constexpr du_ue_index_t ue_id = to_du_ue_index(0); + static constexpr rnti_t ue_rnti = to_rnti(0x4601); srslog::basic_logger& logger = srslog::fetch_basic_logger("SCHED", true); sched_cfg_dummy_notifier notif; diff --git a/tests/unittests/scheduler/uci_and_pucch/uci_allocator_test.cpp b/tests/unittests/scheduler/uci_and_pucch/uci_allocator_test.cpp index a2974aa8f8..c1dd35069b 100644 --- a/tests/unittests/scheduler/uci_and_pucch/uci_allocator_test.cpp +++ b/tests/unittests/scheduler/uci_and_pucch/uci_allocator_test.cpp @@ -475,7 +475,7 @@ TEST_F(test_uci_allocator, uci_multiplexing_3_bit_harq_sr_csi_on_pusch) class test_tdd_uci_allocator : public test_uci_allocator { protected: - constexpr static size_t DAI_MOD = 4; + static constexpr size_t DAI_MOD = 4; test_tdd_uci_allocator() : test_uci_allocator(test_bench_params{.is_tdd = true}) {} }; diff --git a/tests/unittests/scheduler/uci_and_pucch/uci_test_utils.cpp b/tests/unittests/scheduler/uci_and_pucch/uci_test_utils.cpp index 05ae3fca6e..4f55246479 100644 --- a/tests/unittests/scheduler/uci_and_pucch/uci_test_utils.cpp +++ b/tests/unittests/scheduler/uci_and_pucch/uci_test_utils.cpp @@ -211,10 +211,10 @@ test_bench::test_bench(const test_bench_params& params, csi_report.report_slot_offset = params.csi_offset; if (use_format_0) { - pucch_builder_params pucch_params{}; + srs_du::pucch_builder_params pucch_params{}; pucch_params.nof_ue_pucch_f0_or_f1_res_harq = 6; pucch_params.nof_ue_pucch_f2_res_harq = 6; - pucch_params.f0_or_f1_params.emplace(); + pucch_params.f0_or_f1_params.emplace(); pucch_builder.setup( cell_cfg.ul_cfg_common.init_ul_bwp, params.is_tdd ? cell_cfg.tdd_cfg_common : std::nullopt, pucch_params); bool new_ue_added = pucch_builder.add_build_new_ue_pucch_cfg(ue_req.cfg.cells.value().back().serv_cell_cfg); diff --git a/tests/unittests/scheduler/ue_scheduling/ul_logical_channel_test.cpp b/tests/unittests/scheduler/ue_scheduling/ul_logical_channel_test.cpp index ae6b5a6475..6a8f3b78b4 100644 --- a/tests/unittests/scheduler/ue_scheduling/ul_logical_channel_test.cpp +++ b/tests/unittests/scheduler/ue_scheduling/ul_logical_channel_test.cpp @@ -38,7 +38,7 @@ ul_bsr_indication_message make_sbsr(lcg_id_t lcgid, unsigned bsr) unsigned add_header_bytes(lcg_id_t lcgid, unsigned payload_bytes) { // Estimate of the number of bytes required for the upper layer header. - constexpr static unsigned RLC_HEADER_SIZE_ESTIMATE = 3U; + static constexpr unsigned RLC_HEADER_SIZE_ESTIMATE = 3U; // In case of no payload or LCG-ID == 0, there is no need to account for upper layer header. if (payload_bytes == 0) { return 0; diff --git a/tests/unittests/support/unbounded_object_pool_test.cpp b/tests/unittests/support/unbounded_object_pool_test.cpp index 978ecc9470..5e26b71e5b 100644 --- a/tests/unittests/support/unbounded_object_pool_test.cpp +++ b/tests/unittests/support/unbounded_object_pool_test.cpp @@ -16,7 +16,7 @@ using namespace srsran; class unbounded_object_pool_test : public ::testing::Test { protected: - constexpr static size_t init_capacity = 8; + static constexpr size_t init_capacity = 8; unbounded_object_pool pool{init_capacity}; }; From 5950281b85140c96d341bdc2ba8794910a794924 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Wed, 11 Sep 2024 16:17:25 +0200 Subject: [PATCH 015/174] fapi_adaptor: added the MAC to FAPI SRS PDU conversion. --- include/srsran/fapi/message_builders.h | 106 +++++ include/srsran/fapi/messages.h | 47 +-- .../srsran/fapi_adaptor/mac/messages/srs.h | 34 ++ lib/fapi/validators/CMakeLists.txt | 3 +- lib/fapi/validators/message_validators.cpp | 4 + lib/fapi/validators/ul_prach_pdu.cpp | 2 +- lib/fapi/validators/ul_pucch_pdu.cpp | 4 +- lib/fapi/validators/ul_pusch_pdu.cpp | 4 +- lib/fapi/validators/ul_srs_pdu.cpp | 307 ++++++++++++++ lib/fapi/validators/ul_srs_pdu.h | 23 ++ .../mac/mac_to_fapi_translator.cpp | 6 + lib/fapi_adaptor/mac/messages/CMakeLists.txt | 1 + lib/fapi_adaptor/mac/messages/srs.cpp | 55 +++ tests/unittests/fapi/builders/CMakeLists.txt | 4 + .../fapi/builders/ul_srs_pdu_test.cpp | 128 ++++++ .../fapi/message_builder_helpers.cpp | 31 ++ .../unittests/fapi/message_builder_helpers.h | 4 + .../unittests/fapi/validators/CMakeLists.txt | 4 + .../fapi/validators/crc_indication_test.cpp | 2 +- .../fapi/validators/dl_csi_pdu_test.cpp | 2 +- .../fapi/validators/dl_pdcch_pdu_test.cpp | 2 +- .../fapi/validators/dl_pdsch_pdu_test.cpp | 2 +- .../fapi/validators/dl_ssb_pdu_test.cpp | 2 +- .../fapi/validators/dl_tti_request_test.cpp | 2 +- .../fapi/validators/error_indication_test.cpp | 2 +- .../fapi/validators/rach_indication_test.cpp | 2 +- .../validators/rx_data_indication_test.cpp | 2 +- .../fapi/validators/slot_indication_test.cpp | 2 +- .../fapi/validators/srs_indication_test.cpp | 2 +- .../fapi/validators/tx_data_request_test.cpp | 2 +- .../tx_precoding_and_beamforming_pdu_test.cpp | 2 +- .../fapi/validators/ul_dci_request_test.cpp | 2 +- .../fapi/validators/ul_prach_pdu_test.cpp | 2 +- .../fapi/validators/ul_pucch_pdu_test.cpp | 2 +- .../fapi/validators/ul_pusch_pdu_test.cpp | 2 +- .../fapi/validators/ul_srs_pdu_test.cpp | 387 ++++++++++++++++++ .../fapi/validators/ul_tti_request_test.cpp | 2 +- .../fapi_adaptor/mac/messages/CMakeLists.txt | 4 + .../fapi_adaptor/mac/messages/helpers.cpp | 29 ++ .../fapi_adaptor/mac/messages/helpers.h | 8 + .../mac/messages/ul_pusch_pdu_test.cpp | 2 +- .../mac/messages/ul_srs_pdu_test.cpp | 51 +++ 42 files changed, 1236 insertions(+), 48 deletions(-) create mode 100644 include/srsran/fapi_adaptor/mac/messages/srs.h create mode 100644 lib/fapi/validators/ul_srs_pdu.cpp create mode 100644 lib/fapi/validators/ul_srs_pdu.h create mode 100644 lib/fapi_adaptor/mac/messages/srs.cpp create mode 100644 tests/unittests/fapi/builders/ul_srs_pdu_test.cpp create mode 100644 tests/unittests/fapi/validators/ul_srs_pdu_test.cpp create mode 100644 tests/unittests/fapi_adaptor/mac/messages/ul_srs_pdu_test.cpp diff --git a/include/srsran/fapi/message_builders.h b/include/srsran/fapi/message_builders.h index c7e567823b..b0d6e9699b 100644 --- a/include/srsran/fapi/message_builders.h +++ b/include/srsran/fapi/message_builders.h @@ -17,6 +17,7 @@ #include "srsran/ran/pdcch/coreset.h" #include "srsran/ran/pdcch/dci_packing.h" #include "srsran/ran/ptrs/ptrs.h" +#include "srsran/ran/srs/srs_configuration.h" #include "srsran/support/math_utils.h" #include @@ -2520,6 +2521,97 @@ class ul_pusch_pdu_builder } }; +/// Uplink SRS PDU builder that helps to fill in the parameters specified in SCF-222 v4.0 section 3.4.3.3. +class ul_srs_pdu_builder +{ + ul_srs_pdu& pdu; + +public: + explicit ul_srs_pdu_builder(ul_srs_pdu& pdu_) : pdu(pdu_) {} + + /// Sets the SRS PDU basic parameters and returns a reference to the builder. + /// \note These parameters are specified in SCF-222 v4.0 section 3.4.3.3 in table SRS PDU. + ul_srs_pdu_builder& set_basic_parameters(rnti_t rnti, uint32_t handle) + { + pdu.rnti = rnti; + pdu.handle = handle; + + return *this; + } + + /// Sets the SRS PDU BWP parameters and returns a reference to the builder. + /// \note These parameters are specified in SCF-222 v4.0 section 3.4.3.3 in table SRS PDU. + ul_srs_pdu_builder& + set_bwp_parameters(uint16_t bwp_size, uint16_t bwp_start, subcarrier_spacing scs, cyclic_prefix cp) + { + pdu.bwp_size = bwp_size; + pdu.bwp_start = bwp_start; + pdu.scs = scs; + pdu.cp = cp; + + return *this; + } + + /// Sets the SRS PDU timing parameters and returns a reference to the builder. + /// \note These parameters are specified in SCF-222 v4.0 section 3.4.3.3 in table SRS PDU. + ul_srs_pdu_builder& set_timing_params(unsigned time_start_position, srs_periodicity t_srs, unsigned t_offset) + { + pdu.time_start_position = time_start_position; + pdu.t_srs = t_srs; + pdu.t_offset = t_offset; + + return *this; + } + + /// Sets the SRS PDU comb parameters and returns a reference to the builder. + /// \note These parameters are specified in SCF-222 v4.0 section 3.4.3.3 in table SRS PDU. + ul_srs_pdu_builder& set_comb_params(tx_comb_size comb_size, unsigned comb_offset) + { + pdu.comb_size = comb_size; + pdu.comb_offset = comb_offset; + + return *this; + } + + /// Sets the SRS PDU frequency parameters and returns a reference to the builder. + /// \note These parameters are specified in SCF-222 v4.0 section 3.4.3.3 in table SRS PDU. + ul_srs_pdu_builder& set_frequency_params(unsigned frequency_position, + unsigned frequency_shift, + unsigned frequency_hopping, + srs_group_or_sequence_hopping group_or_sequence_hopping) + { + pdu.frequency_position = frequency_position; + pdu.frequency_shift = frequency_shift; + pdu.frequency_hopping = frequency_hopping; + pdu.group_or_sequence_hopping = group_or_sequence_hopping; + + return *this; + } + + /// Sets the SRS PDU parameters and returns a reference to the builder. + /// \note These parameters are specified in SCF-222 v4.0 section 3.4.3.3 in table SRS PDU. + ul_srs_pdu_builder& set_srs_params(unsigned nof_antenna_ports, + unsigned nof_symbols, + srs_nof_symbols nof_repetitions, + unsigned config_index, + unsigned sequence_id, + unsigned bandwidth_index, + unsigned cyclic_shift, + srs_resource_type resource_type) + { + pdu.num_ant_ports = nof_antenna_ports; + pdu.num_symbols = nof_symbols; + pdu.num_repetitions = nof_repetitions; + pdu.config_index = config_index; + pdu.sequence_id = sequence_id; + pdu.bandwidth_index = bandwidth_index; + pdu.cyclic_shift = cyclic_shift; + pdu.resource_type = resource_type; + + return *this; + } +}; + /// UL_TTI.request message builder that helps to fill in the parameters specified in SCF-222 v4.0 section 3.4.3. class ul_tti_request_message_builder { @@ -2626,6 +2718,20 @@ class ul_tti_request_message_builder return builder; } + + /// Adds a SRS PDU to the message and returns a builder that helps to fill the parameters. + /// \note These parameters are specified in SCF-222 v4.0 section 3.4.3.3 in table SRS PDU. + ul_srs_pdu_builder add_srs_pdu() + { + auto& pdu = msg.pdus.emplace_back(); + pdu.pdu_type = ul_pdu_type::SRS; + + ++msg.num_pdus_of_each_type[static_cast(pdu_type::SRS)]; + + ul_srs_pdu_builder builder(pdu.srs_pdu); + + return builder; + } }; } // namespace fapi diff --git a/include/srsran/fapi/messages.h b/include/srsran/fapi/messages.h index 2f6182d15d..e95b855995 100644 --- a/include/srsran/fapi/messages.h +++ b/include/srsran/fapi/messages.h @@ -30,6 +30,7 @@ #include "srsran/ran/sch/modulation_scheme.h" #include "srsran/ran/slot_pdu_capacity_constants.h" #include "srsran/ran/srs/srs_channel_matrix.h" +#include "srsran/ran/srs/srs_configuration.h" #include "srsran/ran/ssb_properties.h" #include "srsran/ran/subcarrier_spacing.h" #include "srsran/ran/uci/uci_configuration.h" @@ -734,29 +735,29 @@ struct ul_srs_params_v4 { /// SRS PDU. struct ul_srs_pdu { - rnti_t rnti; - uint32_t handle; - uint16_t bwp_size; - uint16_t bwp_start; - subcarrier_spacing scs; - cyclic_prefix cp; - uint8_t num_ant_ports; - uint8_t num_symbols; - uint8_t num_repetitions; - uint8_t time_start_position; - uint8_t config_index; - uint16_t sequence_id; - uint8_t bandwidth_index; - uint8_t comb_size; - uint8_t comb_offset; - uint8_t cyclic_shift; - uint8_t frequency_position; - uint16_t frequency_shift; - uint8_t frequency_hopping; - uint8_t group_or_sequence_hopping; - uint8_t resource_type; - uint16_t t_srs; - uint16_t t_offset; + rnti_t rnti; + uint32_t handle; + uint16_t bwp_size; + uint16_t bwp_start; + subcarrier_spacing scs; + cyclic_prefix cp; + uint8_t num_ant_ports; + uint8_t num_symbols; + srs_nof_symbols num_repetitions; + uint8_t time_start_position; + uint8_t config_index; + uint16_t sequence_id; + uint8_t bandwidth_index; + tx_comb_size comb_size; + uint8_t comb_offset; + uint8_t cyclic_shift; + uint8_t frequency_position; + uint16_t frequency_shift; + uint8_t frequency_hopping; + srs_group_or_sequence_hopping group_or_sequence_hopping; + srs_resource_type resource_type; + srs_periodicity t_srs; + uint16_t t_offset; // :TODO: beamforming. ul_srs_params_v4 srs_params_v4; }; diff --git a/include/srsran/fapi_adaptor/mac/messages/srs.h b/include/srsran/fapi_adaptor/mac/messages/srs.h new file mode 100644 index 0000000000..c86a82f918 --- /dev/null +++ b/include/srsran/fapi_adaptor/mac/messages/srs.h @@ -0,0 +1,34 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/fapi/message_builders.h" + +namespace srsran { + +struct srs_info; + +namespace fapi_adaptor { + +/// \brief Helper function that converts from a SRS MAC PDU to a SRS FAPI PDU. +/// +/// \param[out] fapi_pdu SRS FAPI PDU that will store the converted data. +/// \param[in] mac_pdu MAC PDU that contains the SRS parameters. +void convert_srs_mac_to_fapi(fapi::ul_srs_pdu& fapi_pdu, const srs_info& mac_pdu); + +/// \brief Helper function that converts from a SRS MAC PDU to a SRS FAPI PDU. +/// +/// \param[out] fapi_pdu SRS FAPI builder that helps to fill the PDU. +/// \param[in] mac_pdu MAC PDU that contains the SRS parameters. +void convert_srs_mac_to_fapi(fapi::ul_srs_pdu_builder& builder, const srs_info& mac_pdu); + +} // namespace fapi_adaptor +} // namespace srsran diff --git a/lib/fapi/validators/CMakeLists.txt b/lib/fapi/validators/CMakeLists.txt index e1377dcc03..ea08b634fd 100644 --- a/lib/fapi/validators/CMakeLists.txt +++ b/lib/fapi/validators/CMakeLists.txt @@ -16,7 +16,8 @@ set(SOURCES uci_pdus.cpp ul_prach_pdu.cpp ul_pucch_pdu.cpp - ul_pusch_pdu.cpp) + ul_pusch_pdu.cpp + ul_srs_pdu.cpp) add_library(srsran_fapi_validators STATIC ${SOURCES}) target_link_libraries(srsran_fapi_validators srslog) diff --git a/lib/fapi/validators/message_validators.cpp b/lib/fapi/validators/message_validators.cpp index ec36d4c85b..6e00a7e09d 100644 --- a/lib/fapi/validators/message_validators.cpp +++ b/lib/fapi/validators/message_validators.cpp @@ -18,6 +18,7 @@ #include "ul_prach_pdu.h" #include "ul_pucch_pdu.h" #include "ul_pusch_pdu.h" +#include "ul_srs_pdu.h" #include "srsran/support/format_utils.h" using namespace srsran; @@ -724,6 +725,9 @@ error_type srsran::fapi::validate_ul_tti_request(const ul_tti_ case ul_pdu_type::PUSCH: success &= validate_ul_pusch_pdu(pdu.pusch_pdu, report); break; + case ul_pdu_type::SRS: + success &= validate_ul_srs_pdu(pdu.srs_pdu, report); + break; default: srsran_assert(0, "Invalid pdu_type"); break; diff --git a/lib/fapi/validators/ul_prach_pdu.cpp b/lib/fapi/validators/ul_prach_pdu.cpp index a183409db9..49082523b5 100644 --- a/lib/fapi/validators/ul_prach_pdu.cpp +++ b/lib/fapi/validators/ul_prach_pdu.cpp @@ -16,7 +16,7 @@ using namespace srsran; using namespace fapi; -/// This validator checks a DL_TTI.request message. +/// This validator checks a UL_TTI.request message. static constexpr message_type_id msg_type = message_type_id::ul_tti_request; /// This validator checks the PRACH PDU. diff --git a/lib/fapi/validators/ul_pucch_pdu.cpp b/lib/fapi/validators/ul_pucch_pdu.cpp index ba8c0750f9..782a03ff3b 100644 --- a/lib/fapi/validators/ul_pucch_pdu.cpp +++ b/lib/fapi/validators/ul_pucch_pdu.cpp @@ -16,10 +16,10 @@ using namespace srsran; using namespace fapi; -/// This validator checks a DL_TTI.request message. +/// This validator checks a UL_TTI.request message. static constexpr message_type_id msg_type = message_type_id::ul_tti_request; -/// This validator checks the PRACH PDU. +/// This validator checks the PUCCH PDU. static constexpr unsigned pdu_type = static_cast(ul_pdu_type::PUCCH); /// Validates the RNTI property of the PUCCH PDU, as per SCF-222 v4.0 Section 3.4.3.3. diff --git a/lib/fapi/validators/ul_pusch_pdu.cpp b/lib/fapi/validators/ul_pusch_pdu.cpp index 05c5e37e81..2b8c704bd1 100644 --- a/lib/fapi/validators/ul_pusch_pdu.cpp +++ b/lib/fapi/validators/ul_pusch_pdu.cpp @@ -16,10 +16,10 @@ using namespace srsran; using namespace fapi; -/// This validator checks a DL_TTI.request message. +/// This validator checks a UL_TTI.request message. static constexpr message_type_id msg_type = message_type_id::ul_tti_request; -/// This validator checks the PRACH PDU. +/// This validator checks the PUSCH PDU. static constexpr unsigned pdu_type = static_cast(ul_pdu_type::PUSCH); /// Validates the RNTI property of the PUSCH PDU, as per SCF-222 v4.0 Section 3.4.3.2. diff --git a/lib/fapi/validators/ul_srs_pdu.cpp b/lib/fapi/validators/ul_srs_pdu.cpp new file mode 100644 index 0000000000..1ae3a6b142 --- /dev/null +++ b/lib/fapi/validators/ul_srs_pdu.cpp @@ -0,0 +1,307 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "ul_srs_pdu.h" +#include "field_checkers.h" +#include "srsran/fapi/messages.h" +#include "srsran/ran/srs/srs_configuration.h" + +using namespace srsran; +using namespace fapi; + +/// This validator checks a UL_TTI.request message. +static constexpr message_type_id msg_type = message_type_id::ul_tti_request; + +/// This validator checks the SRS PDU. +static constexpr unsigned pdu_type = static_cast(ul_pdu_type::SRS); + +/// Validates the RNTI property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_rnti(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 1; + static constexpr unsigned MAX_VALUE = 65535; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "RNTI", msg_type, pdu_type, report); +} + +/// Validates the BWP size property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_bwp_size(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 1; + static constexpr unsigned MAX_VALUE = 275; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "BWP size", msg_type, pdu_type, report); +} + +/// Validates the BWP start property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_bwp_start(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 274; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "BWP start", msg_type, pdu_type, report); +} + +/// Validates the subcarrier spacing property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3. +static bool validate_scs(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 4; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Subcarrier spacing", msg_type, pdu_type, report); +} + +/// Validates the cyclic prefix property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_cyclic_prefix(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 1; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Cyclic prefix", msg_type, pdu_type, report); +} + +/// Validates the number of antenna ports property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_nof_antenna_ports(unsigned value, validator_report& report) +{ + if (value == 1 || value == 2 || value == 4) { + return true; + } + + report.append(value, "Number of antenna ports", msg_type, pdu_type); + + return false; +} + +/// Validates the number of symbols property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_nof_symbols(unsigned value, validator_report& report) +{ + if (value == 1 || value == 2 || value == 4) { + return true; + } + + report.append(value, "Number of symbols", msg_type, pdu_type); + + return false; +} + +/// Validates the number of repetitions property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_nof_repetitions(srs_nof_symbols value, validator_report& report) +{ + if (value == n1 || value == n2 || value == n4) { + return true; + } + + report.append(static_cast(value), "Number of repetitions", msg_type, pdu_type); + + return false; +} + +/// Validates the time start position property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_time_start_position(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 13; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Time start position", msg_type, pdu_type, report); +} + +/// Validates the config index property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_config_index(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 63; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Config index", msg_type, pdu_type, report); +} + +/// Validates the sequence identifier property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_sequence_id(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 1023; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Sequence identifier", msg_type, pdu_type, report); +} + +/// Validates the bandwidth index property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_bandwidth_index(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 3; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Bandwidth index", msg_type, pdu_type, report); +} + +/// Validates the comb size property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_comb_size(tx_comb_size value, validator_report& report) +{ + if (value == tx_comb_size::n2 || value == tx_comb_size::n4) { + return true; + } + + report.append(static_cast(value), "Comb size", msg_type, pdu_type); + + return false; +} + +/// Validates the comb offset property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_comb_offset(tx_comb_size size, unsigned value, validator_report& report) +{ + if (size == tx_comb_size::n2) { + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 1; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Comb offset", msg_type, pdu_type, report); + } + + if (size == tx_comb_size::n4) { + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 3; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Comb offset", msg_type, pdu_type, report); + } + + report.append(static_cast(value), "Comb ofsset", msg_type, pdu_type); + + return false; +} + +/// Validates the cyclic shift property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_cyclic_shift(tx_comb_size size, unsigned value, validator_report& report) +{ + if (size == tx_comb_size::n2) { + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 7; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Cyclic shift", msg_type, pdu_type, report); + } + + if (size == tx_comb_size::n4) { + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 11; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Cyclic shift", msg_type, pdu_type, report); + } + + report.append(static_cast(value), "Cyclic shift", msg_type, pdu_type); + + return false; +} + +/// Validates the frequency position property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_frequency_position(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 67; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Frequency position", msg_type, pdu_type, report); +} + +/// Validates the frequency shift property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_frequency_shift(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 268; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Frequency shift", msg_type, pdu_type, report); +} + +/// Validates the frequency hopping property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_frequency_hopping(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 3; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Frequency hopping", msg_type, pdu_type, report); +} + +/// Validates the group or sequence hopping property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_group_or_sequence_hopping(srs_group_or_sequence_hopping value, validator_report& report) +{ + if (value == srs_group_or_sequence_hopping::groupHopping || value == srs_group_or_sequence_hopping::sequenceHopping || + value == srs_group_or_sequence_hopping::neither) { + return true; + } + + report.append(static_cast(value), "Group or sequence hopping", msg_type, pdu_type); + + return false; +} + +/// Validates the resource type property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_resource_type(srs_resource_type value, validator_report& report) +{ + if (value == srs_resource_type::aperiodic || value == srs_resource_type::periodic || + value == srs_resource_type::semi_persistent) { + return true; + } + + report.append(static_cast(value), "Resource type", msg_type, pdu_type); + + return false; +} + +/// Validates the periodicity property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_t_srs(srs_periodicity value, validator_report& report) +{ + if (value == srs_periodicity::sl1 || value == srs_periodicity::sl2 || value == srs_periodicity::sl4 || + value == srs_periodicity::sl5 || value == srs_periodicity::sl8 || value == srs_periodicity::sl10 || + value == srs_periodicity::sl16 || value == srs_periodicity::sl20 || value == srs_periodicity::sl32 || + value == srs_periodicity::sl40 || value == srs_periodicity::sl64 || value == srs_periodicity::sl80 || + value == srs_periodicity::sl160 || value == srs_periodicity::sl320 || value == srs_periodicity::sl640 || + value == srs_periodicity::sl1280 || value == srs_periodicity::sl2560) { + return true; + } + + report.append(static_cast(value), "T-SRS", msg_type, pdu_type); + + return false; +} + +/// Validates the slot offset property of the SRS PDU, as per SCF-222 v4.0 Section 3.4.3.3 +static bool validate_t_offset(unsigned value, validator_report& report) +{ + static constexpr unsigned MIN_VALUE = 0; + static constexpr unsigned MAX_VALUE = 2559; + + return validate_field(MIN_VALUE, MAX_VALUE, value, "Slot offset value", msg_type, pdu_type, report); +} + +bool fapi::validate_ul_srs_pdu(const ul_srs_pdu& pdu, validator_report& report) +{ + bool result = true; + + // NOTE: pdu Bitmap property range is not specified and will not be validated. + result &= validate_rnti(static_cast(pdu.rnti), report); + // NOTE: Handle property range is not specified. + result &= validate_bwp_size(pdu.bwp_size, report); + result &= validate_bwp_start(pdu.bwp_start, report); + result &= validate_scs(static_cast(pdu.scs), report); + result &= validate_cyclic_prefix(static_cast(pdu.cp), report); + result &= validate_nof_antenna_ports(pdu.num_ant_ports, report); + result &= validate_nof_symbols(pdu.num_symbols, report); + result &= validate_nof_repetitions(pdu.num_repetitions, report); + result &= validate_time_start_position(pdu.time_start_position, report); + result &= validate_config_index(pdu.config_index, report); + result &= validate_sequence_id(pdu.sequence_id, report); + result &= validate_bandwidth_index(pdu.bandwidth_index, report); + result &= validate_comb_size(pdu.comb_size, report); + result &= validate_comb_offset(pdu.comb_size, pdu.comb_offset, report); + result &= validate_cyclic_shift(pdu.comb_size, pdu.cyclic_shift, report); + result &= validate_frequency_position(pdu.frequency_position, report); + result &= validate_frequency_shift(pdu.frequency_shift, report); + result &= validate_frequency_hopping(pdu.frequency_hopping, report); + result &= validate_group_or_sequence_hopping(pdu.group_or_sequence_hopping, report); + result &= validate_resource_type(pdu.resource_type, report); + result &= validate_t_srs(pdu.t_srs, report); + result &= validate_t_offset(pdu.t_offset, report); + + return result; +} diff --git a/lib/fapi/validators/ul_srs_pdu.h b/lib/fapi/validators/ul_srs_pdu.h new file mode 100644 index 0000000000..3892701a50 --- /dev/null +++ b/lib/fapi/validators/ul_srs_pdu.h @@ -0,0 +1,23 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +namespace srsran { +namespace fapi { + +struct ul_srs_pdu; +struct validator_report; + +/// Validates the given UL SRS PDU and returns true on success, otherwise false. +bool validate_ul_srs_pdu(const ul_srs_pdu& pdu, validator_report& report); + +} // namespace fapi +} // namespace srsran diff --git a/lib/fapi_adaptor/mac/mac_to_fapi_translator.cpp b/lib/fapi_adaptor/mac/mac_to_fapi_translator.cpp index 4381ebafe7..0cca3d55ef 100644 --- a/lib/fapi_adaptor/mac/mac_to_fapi_translator.cpp +++ b/lib/fapi_adaptor/mac/mac_to_fapi_translator.cpp @@ -17,6 +17,7 @@ #include "srsran/fapi_adaptor/mac/messages/prach.h" #include "srsran/fapi_adaptor/mac/messages/pucch.h" #include "srsran/fapi_adaptor/mac/messages/pusch.h" +#include "srsran/fapi_adaptor/mac/messages/srs.h" #include "srsran/fapi_adaptor/mac/messages/ssb.h" using namespace srsran; @@ -289,6 +290,11 @@ void mac_to_fapi_translator::on_new_uplink_scheduler_results(const mac_ul_sched_ convert_pucch_mac_to_fapi(pdu_builder, pdu); } + for (const auto& pdu : ul_res.ul_res->srss) { + fapi::ul_srs_pdu_builder pdu_builder = builder.add_srs_pdu(); + convert_srs_mac_to_fapi(pdu_builder, pdu); + } + // Validate the UL_TTI.request message. error_type result = validate_ul_tti_request(msg); diff --git a/lib/fapi_adaptor/mac/messages/CMakeLists.txt b/lib/fapi_adaptor/mac/messages/CMakeLists.txt index 1cbb7d6b52..38bdbcf4cf 100644 --- a/lib/fapi_adaptor/mac/messages/CMakeLists.txt +++ b/lib/fapi_adaptor/mac/messages/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCES prach.cpp pucch.cpp pusch.cpp + srs.cpp ssb.cpp) add_library(srsran_mac_fapi_adaptors STATIC ${SOURCES}) diff --git a/lib/fapi_adaptor/mac/messages/srs.cpp b/lib/fapi_adaptor/mac/messages/srs.cpp new file mode 100644 index 0000000000..5afd45b0e1 --- /dev/null +++ b/lib/fapi_adaptor/mac/messages/srs.cpp @@ -0,0 +1,55 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsran/fapi_adaptor/mac/messages/srs.h" +#include "srsran/scheduler/scheduler_slot_handler.h" + +using namespace srsran; +using namespace fapi_adaptor; + +void fapi_adaptor::convert_srs_mac_to_fapi(fapi::ul_srs_pdu& fapi_pdu, const srs_info& mac_pdu) +{ + fapi::ul_srs_pdu_builder builder(fapi_pdu); + + convert_srs_mac_to_fapi(builder, mac_pdu); +} + +void fapi_adaptor::convert_srs_mac_to_fapi(fapi::ul_srs_pdu_builder& builder, const srs_info& mac_pdu) +{ + static constexpr unsigned handle = 0; + + // Basic parameters. + builder.set_basic_parameters(mac_pdu.crnti, handle); + + // BWP parameters. + const bwp_configuration& bwp = *mac_pdu.bwp_cfg; + builder.set_bwp_parameters(bwp.crbs.length(), bwp.crbs.start(), bwp.scs, bwp.cp); + + // Frequency parameters. + builder.set_frequency_params( + mac_pdu.freq_position, mac_pdu.freq_shift, mac_pdu.freq_hopping, mac_pdu.group_or_seq_hopping); + + // Comb parameters. + builder.set_comb_params(mac_pdu.tx_comb, mac_pdu.comb_offset); + + // Timing parameters. + static constexpr unsigned time_start_position = 0; + builder.set_timing_params(time_start_position, mac_pdu.t_srs_period, mac_pdu.t_offset); + + // Rest of the parameters. + builder.set_srs_params(mac_pdu.nof_antenna_ports, + mac_pdu.symbols.length(), + mac_pdu.nof_repetitions, + mac_pdu.config_index, + mac_pdu.sequence_id, + mac_pdu.bw_index, + mac_pdu.cyclic_shift, + mac_pdu.resource_type); +} diff --git a/tests/unittests/fapi/builders/CMakeLists.txt b/tests/unittests/fapi/builders/CMakeLists.txt index 4bed8cb32f..18cd384b07 100644 --- a/tests/unittests/fapi/builders/CMakeLists.txt +++ b/tests/unittests/fapi/builders/CMakeLists.txt @@ -80,6 +80,10 @@ add_executable(ul_pusch_builder_test ul_pusch_pdu_test.cpp) target_link_libraries(ul_pusch_builder_test srsran_support srslog gtest gtest_main) gtest_discover_tests(ul_pusch_builder_test) +add_executable(ul_srs_builder_test ul_srs_pdu_test.cpp) +target_link_libraries(ul_srs_builder_test srsran_support srslog gtest gtest_main) +gtest_discover_tests(ul_srs_builder_test) + add_executable(ul_tti_request_builder_test ul_tti_request_test.cpp) target_link_libraries(ul_tti_request_builder_test srsran_support srslog gtest gtest_main) gtest_discover_tests(ul_tti_request_builder_test) diff --git a/tests/unittests/fapi/builders/ul_srs_pdu_test.cpp b/tests/unittests/fapi/builders/ul_srs_pdu_test.cpp new file mode 100644 index 0000000000..dd06dbfbd5 --- /dev/null +++ b/tests/unittests/fapi/builders/ul_srs_pdu_test.cpp @@ -0,0 +1,128 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsran/fapi/message_builders.h" +#include + +using namespace srsran; +using namespace fapi; + +TEST(ul_srs_pdu_builder, valid_basic_parameters_passes) +{ + rnti_t rnti = to_rnti(245); + unsigned handle = 100021; + + ul_srs_pdu pdu; + ul_srs_pdu_builder builder(pdu); + + builder.set_basic_parameters(rnti, handle); + + ASSERT_EQ(rnti, pdu.rnti); + ASSERT_EQ(handle, pdu.handle); +} + +TEST(ul_srs_pdu_builder, valid_bwp_parameters_passes) +{ + unsigned bwp_start = 100; + unsigned bwp_size = 69; + subcarrier_spacing scs = subcarrier_spacing::kHz30; + cyclic_prefix cp = cyclic_prefix::EXTENDED; + + ul_srs_pdu pdu; + ul_srs_pdu_builder builder(pdu); + + builder.set_bwp_parameters(bwp_size, bwp_start, scs, cp); + + ASSERT_EQ(bwp_size, pdu.bwp_size); + ASSERT_EQ(bwp_start, pdu.bwp_start); + ASSERT_EQ(scs, pdu.scs); + ASSERT_EQ(cp, pdu.cp); +} + +TEST(ul_srs_pdu_builder, valid_timing_parameters_passes) +{ + unsigned t_offset = 2; + srs_periodicity t_srs = srs_periodicity::sl1; + unsigned time_start_position = 3; + + ul_srs_pdu pdu; + ul_srs_pdu_builder builder(pdu); + + builder.set_timing_params(time_start_position, t_srs, t_offset); + + ASSERT_EQ(time_start_position, pdu.time_start_position); + ASSERT_EQ(t_srs, pdu.t_srs); + ASSERT_EQ(t_offset, pdu.t_offset); +} + +TEST(ul_srs_pdu_builder, valid_comb_parameters_passes) +{ + unsigned comb_offset = 2; + tx_comb_size comb_size = tx_comb_size::n2; + + ul_srs_pdu pdu; + ul_srs_pdu_builder builder(pdu); + + builder.set_comb_params(comb_size, comb_offset); + + ASSERT_EQ(comb_offset, pdu.comb_offset); + ASSERT_EQ(comb_size, pdu.comb_size); +} + +TEST(ul_srs_pdu_builder, valid_frequency_parameters_passes) +{ + unsigned frequency_position = 4; + unsigned frequency_shift = 3; + unsigned frequency_hopping = 2; + srs_group_or_sequence_hopping group_or_sequence_hopping = srs_group_or_sequence_hopping::neither; + + ul_srs_pdu pdu; + ul_srs_pdu_builder builder(pdu); + + builder.set_frequency_params(frequency_position, frequency_shift, frequency_hopping, group_or_sequence_hopping); + + ASSERT_EQ(frequency_position, pdu.frequency_position); + ASSERT_EQ(frequency_shift, pdu.frequency_shift); + ASSERT_EQ(frequency_hopping, pdu.frequency_hopping); + ASSERT_EQ(group_or_sequence_hopping, pdu.group_or_sequence_hopping); +} + +TEST(ul_srs_pdu_builder, valid_srs_parameters_passes) +{ + unsigned nof_antenna_ports = 4; + unsigned nof_symbols = 3; + srs_nof_symbols nof_repetitions = n1; + unsigned config_index = 2; + unsigned sequence_id = 5; + unsigned bandwidth_index = 6; + unsigned cyclic_shift = 7; + srs_resource_type resource_type = srs_resource_type::aperiodic; + + ul_srs_pdu pdu; + ul_srs_pdu_builder builder(pdu); + + builder.set_srs_params(nof_antenna_ports, + nof_symbols, + nof_repetitions, + config_index, + sequence_id, + bandwidth_index, + cyclic_shift, + resource_type); + + ASSERT_EQ(nof_antenna_ports, pdu.num_ant_ports); + ASSERT_EQ(nof_symbols, pdu.num_symbols); + ASSERT_EQ(nof_repetitions, pdu.num_repetitions); + ASSERT_EQ(config_index, pdu.config_index); + ASSERT_EQ(sequence_id, pdu.sequence_id); + ASSERT_EQ(bandwidth_index, pdu.bandwidth_index); + ASSERT_EQ(cyclic_shift, pdu.cyclic_shift); + ASSERT_EQ(resource_type, pdu.resource_type); +} diff --git a/tests/unittests/fapi/message_builder_helpers.cpp b/tests/unittests/fapi/message_builder_helpers.cpp index cdb79f985c..61d0aa8eef 100644 --- a/tests/unittests/fapi/message_builder_helpers.cpp +++ b/tests/unittests/fapi/message_builder_helpers.cpp @@ -1078,6 +1078,37 @@ ul_pusch_pdu unittest::build_valid_ul_pusch_pdu() return pdu; } + +ul_srs_pdu unittest::build_valid_ul_srs_pdu() +{ + ul_srs_pdu pdu; + pdu.rnti = to_rnti(23); + pdu.handle = 8; + pdu.bwp_size = 230; + pdu.bwp_start = 10; + pdu.scs = subcarrier_spacing::kHz30; + pdu.cp = cyclic_prefix::NORMAL; + pdu.num_ant_ports = 2; + pdu.num_symbols = 1; + pdu.num_repetitions = n1; + pdu.time_start_position = 3; + pdu.config_index = 4; + pdu.sequence_id = 6; + pdu.bandwidth_index = 1; + pdu.comb_size = tx_comb_size::n2; + pdu.comb_offset = 1; + pdu.cyclic_shift = 0; + pdu.frequency_position = 3; + pdu.frequency_shift = 10; + pdu.frequency_hopping = 2; + pdu.group_or_sequence_hopping = srs_group_or_sequence_hopping::neither; + pdu.resource_type = srs_resource_type::periodic; + pdu.t_srs = srs_periodicity::sl4; + pdu.t_offset = 2; + + return pdu; +} + ul_tti_request_message unittest::build_valid_ul_tti_request() { ul_tti_request_message msg; diff --git a/tests/unittests/fapi/message_builder_helpers.h b/tests/unittests/fapi/message_builder_helpers.h index 11d2cac0c7..89d2427960 100644 --- a/tests/unittests/fapi/message_builder_helpers.h +++ b/tests/unittests/fapi/message_builder_helpers.h @@ -130,6 +130,10 @@ srsran::fapi::ul_pucch_pdu build_valid_ul_pucch_f4_pdu(); /// Section 3.4.3.2. srsran::fapi::ul_pusch_pdu build_valid_ul_pusch_pdu(); +/// Builds and returns a valid UL SRS PDU. Every parameter is within the range defined in SCF-222 v4.0 +/// Section 3.4.3.3. +srsran::fapi::ul_srs_pdu build_valid_ul_srs_pdu(); + /// Builds and returns a valid UL_TTI.request. Every parameter is within the range defined in SCF-222 v4.0 /// Section 3.4.3. srsran::fapi::ul_tti_request_message build_valid_ul_tti_request(); diff --git a/tests/unittests/fapi/validators/CMakeLists.txt b/tests/unittests/fapi/validators/CMakeLists.txt index 472952de21..ebed12c29d 100644 --- a/tests/unittests/fapi/validators/CMakeLists.txt +++ b/tests/unittests/fapi/validators/CMakeLists.txt @@ -80,6 +80,10 @@ add_executable(ul_pusch_pdu_validator_test ul_pusch_pdu_test.cpp) target_link_libraries(ul_pusch_pdu_validator_test srsran_support srsran_fapi_message_builder_test_helpers srslog srsran_fapi gtest gtest_main) gtest_discover_tests(ul_pusch_pdu_validator_test) +add_executable(ul_srs_pdu_validator_test ul_srs_pdu_test.cpp) +target_link_libraries(ul_srs_pdu_validator_test srsran_support srsran_fapi_message_builder_test_helpers srslog srsran_fapi gtest gtest_main) +gtest_discover_tests(ul_srs_pdu_validator_test) + add_executable(ul_tti_request_validator_test ul_tti_request_test.cpp) target_link_libraries(ul_tti_request_validator_test srsran_support srsran_fapi_message_builder_test_helpers srslog srsran_fapi gtest gtest_main) gtest_discover_tests(ul_tti_request_validator_test) diff --git a/tests/unittests/fapi/validators/crc_indication_test.cpp b/tests/unittests/fapi/validators/crc_indication_test.cpp index 1e3fdc83e8..425c5a64b9 100644 --- a/tests/unittests/fapi/validators/crc_indication_test.cpp +++ b/tests/unittests/fapi/validators/crc_indication_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_crc_message_field, WithValue) build_valid_crc_indication, validate_crc_indication, srsran::fapi::message_type_id::crc_indication); -}; +} INSTANTIATE_TEST_SUITE_P(SFN, validate_crc_message_field, diff --git a/tests/unittests/fapi/validators/dl_csi_pdu_test.cpp b/tests/unittests/fapi/validators/dl_csi_pdu_test.cpp index 08ff6572dc..8cc2046b88 100644 --- a/tests/unittests/fapi/validators/dl_csi_pdu_test.cpp +++ b/tests/unittests/fapi/validators/dl_csi_pdu_test.cpp @@ -31,7 +31,7 @@ TEST_P(validate_csi_pdu_field, WithValue) validate_dl_csi_pdu, srsran::fapi::message_type_id::dl_tti_request, dl_pdu_type::CSI_RS); -}; +} INSTANTIATE_TEST_SUITE_P(Subcarrier_spacing, validate_csi_pdu_field, diff --git a/tests/unittests/fapi/validators/dl_pdcch_pdu_test.cpp b/tests/unittests/fapi/validators/dl_pdcch_pdu_test.cpp index 2fceda1ffb..95b8bd5c5c 100644 --- a/tests/unittests/fapi/validators/dl_pdcch_pdu_test.cpp +++ b/tests/unittests/fapi/validators/dl_pdcch_pdu_test.cpp @@ -36,7 +36,7 @@ TEST_P(validate_pdcch_pdu_field, WithValue) validator, srsran::fapi::message_type_id::dl_tti_request, dl_pdu_type::PDCCH); -}; +} INSTANTIATE_TEST_SUITE_P(coreset_bwp_size, validate_pdcch_pdu_field, diff --git a/tests/unittests/fapi/validators/dl_pdsch_pdu_test.cpp b/tests/unittests/fapi/validators/dl_pdsch_pdu_test.cpp index baec42d8f8..61d941a80d 100644 --- a/tests/unittests/fapi/validators/dl_pdsch_pdu_test.cpp +++ b/tests/unittests/fapi/validators/dl_pdsch_pdu_test.cpp @@ -31,7 +31,7 @@ TEST_P(validate_pdsch_pdu_field, WithValue) validate_dl_pdsch_pdu, srsran::fapi::message_type_id::dl_tti_request, dl_pdu_type::PDSCH); -}; +} INSTANTIATE_TEST_SUITE_P(rnti, validate_pdsch_pdu_field, diff --git a/tests/unittests/fapi/validators/dl_ssb_pdu_test.cpp b/tests/unittests/fapi/validators/dl_ssb_pdu_test.cpp index 25286eec1b..34472a9201 100644 --- a/tests/unittests/fapi/validators/dl_ssb_pdu_test.cpp +++ b/tests/unittests/fapi/validators/dl_ssb_pdu_test.cpp @@ -31,7 +31,7 @@ TEST_P(validate_ssb_pdu_field, WithValue) validate_dl_ssb_pdu, srsran::fapi::message_type_id::dl_tti_request, dl_pdu_type::SSB); -}; +} INSTANTIATE_TEST_SUITE_P(pci, validate_ssb_pdu_field, diff --git a/tests/unittests/fapi/validators/dl_tti_request_test.cpp b/tests/unittests/fapi/validators/dl_tti_request_test.cpp index 48e0f35825..cf9ee22c5a 100644 --- a/tests/unittests/fapi/validators/dl_tti_request_test.cpp +++ b/tests/unittests/fapi/validators/dl_tti_request_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_dl_tti_request_field, with_value) build_valid_dl_tti_request, validate_dl_tti_request, srsran::fapi::message_type_id::dl_tti_request); -}; +} INSTANTIATE_TEST_SUITE_P(sfn, validate_dl_tti_request_field, diff --git a/tests/unittests/fapi/validators/error_indication_test.cpp b/tests/unittests/fapi/validators/error_indication_test.cpp index 30c0be6238..903c6f49ad 100644 --- a/tests/unittests/fapi/validators/error_indication_test.cpp +++ b/tests/unittests/fapi/validators/error_indication_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_error_indication_field, WithValue) build_valid_error_indication, validate_error_indication, srsran::fapi::message_type_id::error_indication); -}; +} INSTANTIATE_TEST_SUITE_P(SFN, validate_error_indication_field, diff --git a/tests/unittests/fapi/validators/rach_indication_test.cpp b/tests/unittests/fapi/validators/rach_indication_test.cpp index 3409185ffd..d5e288e8f2 100644 --- a/tests/unittests/fapi/validators/rach_indication_test.cpp +++ b/tests/unittests/fapi/validators/rach_indication_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_rach_indication_field, with_value) build_valid_rach_indication, validate_rach_indication, srsran::fapi::message_type_id::rach_indication); -}; +} INSTANTIATE_TEST_SUITE_P(sfn, validate_rach_indication_field, diff --git a/tests/unittests/fapi/validators/rx_data_indication_test.cpp b/tests/unittests/fapi/validators/rx_data_indication_test.cpp index 2db67dd241..f0e4d2125e 100644 --- a/tests/unittests/fapi/validators/rx_data_indication_test.cpp +++ b/tests/unittests/fapi/validators/rx_data_indication_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_rx_data_indication_field, WithValue) build_valid_rx_data_indication, validate_rx_data_indication, srsran::fapi::message_type_id::rx_data_indication); -}; +} INSTANTIATE_TEST_SUITE_P(sfn, validate_rx_data_indication_field, diff --git a/tests/unittests/fapi/validators/slot_indication_test.cpp b/tests/unittests/fapi/validators/slot_indication_test.cpp index 0b77c2b677..1bfaf9cf20 100644 --- a/tests/unittests/fapi/validators/slot_indication_test.cpp +++ b/tests/unittests/fapi/validators/slot_indication_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_slot_indication_field, WithValue) build_valid_slot_indication, validate_slot_indication, srsran::fapi::message_type_id::slot_indication); -}; +} INSTANTIATE_TEST_SUITE_P(SFN, validate_slot_indication_field, diff --git a/tests/unittests/fapi/validators/srs_indication_test.cpp b/tests/unittests/fapi/validators/srs_indication_test.cpp index b03b6285f0..96db502fa4 100644 --- a/tests/unittests/fapi/validators/srs_indication_test.cpp +++ b/tests/unittests/fapi/validators/srs_indication_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_srs_indication_field, WithValue) build_valid_srs_indication, validate_srs_indication, srsran::fapi::message_type_id::srs_indication); -}; +} INSTANTIATE_TEST_SUITE_P(sfn, validate_srs_indication_field, diff --git a/tests/unittests/fapi/validators/tx_data_request_test.cpp b/tests/unittests/fapi/validators/tx_data_request_test.cpp index 7c3a0c359d..74ba4c5546 100644 --- a/tests/unittests/fapi/validators/tx_data_request_test.cpp +++ b/tests/unittests/fapi/validators/tx_data_request_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_tx_data_request_field, with_value) build_valid_tx_data_request, validate_tx_data_request, srsran::fapi::message_type_id::tx_data_request); -}; +} INSTANTIATE_TEST_SUITE_P(sfn, validate_tx_data_request_field, diff --git a/tests/unittests/fapi/validators/tx_precoding_and_beamforming_pdu_test.cpp b/tests/unittests/fapi/validators/tx_precoding_and_beamforming_pdu_test.cpp index 2537d3144d..3ffafd8e89 100644 --- a/tests/unittests/fapi/validators/tx_precoding_and_beamforming_pdu_test.cpp +++ b/tests/unittests/fapi/validators/tx_precoding_and_beamforming_pdu_test.cpp @@ -31,7 +31,7 @@ TEST_P(validate_tx_precoding_and_beamforming_pdu_field, WithValue) validate_tx_precoding_and_beamforming_pdu, srsran::fapi::message_type_id::dl_tti_request, dl_pdu_type::SSB); -}; +} INSTANTIATE_TEST_SUITE_P(nof_prgs, validate_tx_precoding_and_beamforming_pdu_field, diff --git a/tests/unittests/fapi/validators/ul_dci_request_test.cpp b/tests/unittests/fapi/validators/ul_dci_request_test.cpp index 4724c47d24..0ef9bb1a3a 100644 --- a/tests/unittests/fapi/validators/ul_dci_request_test.cpp +++ b/tests/unittests/fapi/validators/ul_dci_request_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_ul_dci_request_field, with_value) build_valid_ul_dci_request, validate_ul_dci_request, srsran::fapi::message_type_id::ul_dci_request); -}; +} INSTANTIATE_TEST_SUITE_P(sfn, validate_ul_dci_request_field, diff --git a/tests/unittests/fapi/validators/ul_prach_pdu_test.cpp b/tests/unittests/fapi/validators/ul_prach_pdu_test.cpp index b10b2cf4df..82dcc67298 100644 --- a/tests/unittests/fapi/validators/ul_prach_pdu_test.cpp +++ b/tests/unittests/fapi/validators/ul_prach_pdu_test.cpp @@ -31,7 +31,7 @@ TEST_P(validate_prach_pdu_field, WithValue) validate_ul_prach_pdu, srsran::fapi::message_type_id::ul_tti_request, ul_pdu_type::PRACH); -}; +} INSTANTIATE_TEST_SUITE_P(pci, validate_prach_pdu_field, diff --git a/tests/unittests/fapi/validators/ul_pucch_pdu_test.cpp b/tests/unittests/fapi/validators/ul_pucch_pdu_test.cpp index d0cc0cfd69..1346ad2fce 100644 --- a/tests/unittests/fapi/validators/ul_pucch_pdu_test.cpp +++ b/tests/unittests/fapi/validators/ul_pucch_pdu_test.cpp @@ -33,7 +33,7 @@ TEST_P(validate_pucch_pdu_common_field, WithValue) validate_ul_pucch_pdu, srsran::fapi::message_type_id::ul_tti_request, ul_pdu_type::PUCCH); -}; +} INSTANTIATE_TEST_SUITE_P(pci, validate_pucch_pdu_common_field, diff --git a/tests/unittests/fapi/validators/ul_pusch_pdu_test.cpp b/tests/unittests/fapi/validators/ul_pusch_pdu_test.cpp index d61b5dbfdd..3a55091ebe 100644 --- a/tests/unittests/fapi/validators/ul_pusch_pdu_test.cpp +++ b/tests/unittests/fapi/validators/ul_pusch_pdu_test.cpp @@ -31,7 +31,7 @@ TEST_P(validate_pusch_pdu_field, WithValue) validate_ul_pusch_pdu, srsran::fapi::message_type_id::ul_tti_request, ul_pdu_type::PUSCH); -}; +} INSTANTIATE_TEST_SUITE_P(RNTI, validate_pusch_pdu_field, diff --git a/tests/unittests/fapi/validators/ul_srs_pdu_test.cpp b/tests/unittests/fapi/validators/ul_srs_pdu_test.cpp new file mode 100644 index 0000000000..b4a46adccb --- /dev/null +++ b/tests/unittests/fapi/validators/ul_srs_pdu_test.cpp @@ -0,0 +1,387 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "../../../lib/fapi/validators/ul_srs_pdu.h" +#include "../message_builder_helpers.h" +#include "helpers.h" +#include "srsran/fapi/message_validators.h" + +using namespace srsran; +using namespace fapi; +using namespace unittest; + +class validate_srs_pdu_field : public validate_fapi_pdu, + public testing::TestWithParam, test_case_data>> +{}; + +TEST_P(validate_srs_pdu_field, WithValue) +{ + auto params = GetParam(); + + execute_test(std::get<0>(params), + std::get<1>(params), + build_valid_ul_srs_pdu, + validate_ul_srs_pdu, + srsran::fapi::message_type_id::ul_tti_request, + ul_pdu_type::SRS); +} + +INSTANTIATE_TEST_SUITE_P(RNTI, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "RNTI", + [](ul_srs_pdu& pdu, int value) { pdu.rnti = to_rnti(value); }}), + testing::Values(test_case_data{0, false}, + test_case_data{1, true}, + test_case_data{32768, true}, + test_case_data{65535, true}))); + +INSTANTIATE_TEST_SUITE_P(BWP_Size, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "BWP size", + [](ul_srs_pdu& pdu, int value) { pdu.bwp_size = value; }}), + testing::Values(test_case_data{0, false}, + test_case_data{1, true}, + test_case_data{128, true}, + test_case_data{275, true}, + test_case_data{276, false}))); + +INSTANTIATE_TEST_SUITE_P(BWP_Start, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "BWP start", + [](ul_srs_pdu& pdu, int value) { pdu.bwp_start = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{128, true}, + test_case_data{274, true}, + test_case_data{275, false}))); + +INSTANTIATE_TEST_SUITE_P(Subcarrier_spacing, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"Subcarrier spacing", + [](ul_srs_pdu& pdu, int value) { + pdu.scs = + to_subcarrier_spacing(value); + }}), + testing::Values(test_case_data{0, true}, + test_case_data{2, true}, + test_case_data{4, true}, + test_case_data{5, false}))); + +INSTANTIATE_TEST_SUITE_P( + Cyclic_prefix, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Cyclic prefix", + [](ul_srs_pdu& pdu, int value) { pdu.cp = static_cast(value); }}), + testing::Values(test_case_data{0, true}, test_case_data{1, true}, test_case_data{2, false}))); + +INSTANTIATE_TEST_SUITE_P(nof_antenna_port, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Number of antenna ports", + [](ul_srs_pdu& pdu, int value) { pdu.num_ant_ports = value; }}), + testing::Values(test_case_data{0, false}, + test_case_data{1, true}, + test_case_data{2, true}, + test_case_data{3, false}, + test_case_data{4, true}, + test_case_data{5, false}))); + +INSTANTIATE_TEST_SUITE_P(nof_symbols, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Number of symbols", + [](ul_srs_pdu& pdu, int value) { pdu.num_symbols = value; }}), + testing::Values(test_case_data{0, false}, + test_case_data{1, true}, + test_case_data{2, true}, + test_case_data{3, false}, + test_case_data{4, true}, + test_case_data{5, false}))); + +INSTANTIATE_TEST_SUITE_P(nof_repetitions, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"Number of repetitions", + [](ul_srs_pdu& pdu, int value) { + pdu.num_repetitions = + static_cast( + value); + }}), + testing::Values(test_case_data{0, false}, + test_case_data{1, true}, + test_case_data{2, true}, + test_case_data{3, false}, + test_case_data{4, true}, + test_case_data{5, false}))); + +INSTANTIATE_TEST_SUITE_P(time_start_position, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Time start position", + [](ul_srs_pdu& pdu, int value) { pdu.time_start_position = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{6, true}, + test_case_data{13, true}, + test_case_data{14, false}, + test_case_data{15, false}))); + +INSTANTIATE_TEST_SUITE_P(config_index, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Config index", + [](ul_srs_pdu& pdu, int value) { pdu.config_index = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{32, true}, + test_case_data{63, true}, + test_case_data{64, false}, + test_case_data{65, false}))); + +INSTANTIATE_TEST_SUITE_P(sequence_id, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Sequence identifier", + [](ul_srs_pdu& pdu, int value) { pdu.sequence_id = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{512, true}, + test_case_data{1023, true}, + test_case_data{1024, false}, + test_case_data{1025, false}))); + +INSTANTIATE_TEST_SUITE_P(bandwidth_index, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Bandwidth index", + [](ul_srs_pdu& pdu, int value) { pdu.bandwidth_index = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{2, true}, + test_case_data{3, true}, + test_case_data{4, false}, + test_case_data{5, false}))); + +INSTANTIATE_TEST_SUITE_P(comb_size, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"Comb size", + [](ul_srs_pdu& pdu, int value) { + pdu.comb_size = + static_cast( + value); + }}), + testing::Values(test_case_data{2, true}, test_case_data{4, true}))); + +INSTANTIATE_TEST_SUITE_P(comb_offset_n2, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"Comb offset", + [](ul_srs_pdu& pdu, int value) { + pdu.comb_size = tx_comb_size::n2; + pdu.comb_offset = value; + }}), + testing::Values(test_case_data{0, true}, + test_case_data{1, true}, + test_case_data{2, false}, + test_case_data{3, false}, + test_case_data{4, false}))); + +INSTANTIATE_TEST_SUITE_P(comb_offset_n4, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"Comb offset", + [](ul_srs_pdu& pdu, int value) { + pdu.comb_size = tx_comb_size::n4; + pdu.comb_offset = value; + }}), + testing::Values(test_case_data{0, true}, + test_case_data{2, true}, + test_case_data{3, true}, + test_case_data{4, false}, + test_case_data{5, false}))); + +INSTANTIATE_TEST_SUITE_P(cyclic_shift_n2, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"Cyclic shift", + [](ul_srs_pdu& pdu, int value) { + pdu.comb_size = tx_comb_size::n2; + pdu.cyclic_shift = value; + }}), + testing::Values(test_case_data{0, true}, + test_case_data{3, true}, + test_case_data{7, true}, + test_case_data{8, false}, + test_case_data{9, false}))); + +INSTANTIATE_TEST_SUITE_P(cyclic_shift_n4, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"Cyclic shift", + [](ul_srs_pdu& pdu, int value) { + pdu.comb_size = tx_comb_size::n4; + pdu.cyclic_shift = value; + }}), + testing::Values(test_case_data{0, true}, + test_case_data{5, true}, + test_case_data{11, true}, + test_case_data{12, false}, + test_case_data{15, false}))); + +INSTANTIATE_TEST_SUITE_P(frequency_position, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Frequency position", + [](ul_srs_pdu& pdu, int value) { pdu.frequency_position = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{32, true}, + test_case_data{67, true}, + test_case_data{68, false}, + test_case_data{105, false}))); + +INSTANTIATE_TEST_SUITE_P(frequency_shift, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Frequency shift", + [](ul_srs_pdu& pdu, int value) { pdu.frequency_shift = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{128, true}, + test_case_data{268, true}, + test_case_data{269, false}, + test_case_data{1005, false}))); + +INSTANTIATE_TEST_SUITE_P(frequency_hopping, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Frequency hopping", + [](ul_srs_pdu& pdu, int value) { pdu.frequency_hopping = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{2, true}, + test_case_data{3, true}, + test_case_data{4, false}, + test_case_data{5, false}))); + +INSTANTIATE_TEST_SUITE_P(group_or_sequence_hopping, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Group or sequence hopping", + [](ul_srs_pdu& pdu, int value) { + pdu.group_or_sequence_hopping = + static_cast(value); + }}), + testing::Values(test_case_data{0, true}, + test_case_data{1, true}, + test_case_data{2, true}, + test_case_data{3, false}, + test_case_data{4, false}))); + +INSTANTIATE_TEST_SUITE_P(resource_type, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Resource type", + [](ul_srs_pdu& pdu, int value) { + pdu.resource_type = static_cast(value); + }}), + testing::Values(test_case_data{0, true}, + test_case_data{1, true}, + test_case_data{2, true}, + test_case_data{3, false}, + test_case_data{4, false}))); + +INSTANTIATE_TEST_SUITE_P(t_srs, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{"T-SRS", + [](ul_srs_pdu& pdu, int value) { + pdu.t_srs = + static_cast( + value); + }}), + testing::Values(test_case_data{0, false}, + test_case_data{1, true}, + test_case_data{2, true}, + test_case_data{3, false}, + test_case_data{4, true}, + test_case_data{5, true}, + test_case_data{6, false}, + test_case_data{7, false}, + test_case_data{8, true}, + test_case_data{9, false}, + test_case_data{10, true}, + test_case_data{11, false}, + test_case_data{15, false}, + test_case_data{16, true}, + test_case_data{17, false}, + test_case_data{19, false}, + test_case_data{20, true}, + test_case_data{21, false}, + test_case_data{31, false}, + test_case_data{32, true}, + test_case_data{33, false}, + test_case_data{39, false}, + test_case_data{40, true}, + test_case_data{41, false}, + test_case_data{63, false}, + test_case_data{64, true}, + test_case_data{65, false}, + test_case_data{79, false}, + test_case_data{80, true}, + test_case_data{81, false}, + test_case_data{159, false}, + test_case_data{160, true}, + test_case_data{161, false}, + test_case_data{319, false}, + test_case_data{320, true}, + test_case_data{321, false}, + test_case_data{639, false}, + test_case_data{640, true}, + test_case_data{641, false}, + test_case_data{1279, false}, + test_case_data{1280, true}, + test_case_data{1281, false}, + test_case_data{2559, false}, + test_case_data{2560, true}, + test_case_data{2561, false}))); + +INSTANTIATE_TEST_SUITE_P(t_offset, + validate_srs_pdu_field, + testing::Combine(testing::Values(pdu_field_data{ + "Slot offset value", + [](ul_srs_pdu& pdu, int value) { pdu.t_offset = value; }}), + testing::Values(test_case_data{0, true}, + test_case_data{1200, true}, + test_case_data{2559, true}, + test_case_data{2560, false}, + test_case_data{3000, false}))); + +/// Valid PDU should pass. +TEST(validate_srs_pdu, valid_pdu_passes) +{ + validator_report report(0, 0); + const auto& pdu = build_valid_ul_srs_pdu(); + EXPECT_TRUE(validate_ul_srs_pdu(pdu, report)); + // Assert no reports were generated. + EXPECT_TRUE(report.reports.empty()); +} + +/// Add 4 errors and check that validation fails with 3 errors. +TEST(validate_srs_pdu, invalid_pdu_fails) +{ + validator_report report(0, 0); + auto pdu = build_valid_ul_srs_pdu(); + + // Add 4 errors. + pdu.bwp_start = 6500; + pdu.bwp_size = 2133; + pdu.config_index = 132; + pdu.bandwidth_index = 8; + + EXPECT_FALSE(validate_ul_srs_pdu(pdu, report)); + ASSERT_EQ(4U, report.reports.size()); + // Check that the properties that caused the error are different. + for (unsigned i = 0, e = report.reports.size(); i != e; ++i) { + for (unsigned j = i + 1; j != e; ++j) { + EXPECT_TRUE(std::strcmp(report.reports[i].property_name, report.reports[j].property_name) != 0); + } + } +} diff --git a/tests/unittests/fapi/validators/ul_tti_request_test.cpp b/tests/unittests/fapi/validators/ul_tti_request_test.cpp index 0e04d86e07..a6fcf5a0dd 100644 --- a/tests/unittests/fapi/validators/ul_tti_request_test.cpp +++ b/tests/unittests/fapi/validators/ul_tti_request_test.cpp @@ -30,7 +30,7 @@ TEST_P(validate_ul_tti_request_field, with_value) build_valid_ul_tti_request, validate_ul_tti_request, srsran::fapi::message_type_id::ul_tti_request); -}; +} INSTANTIATE_TEST_SUITE_P(sfn, validate_ul_tti_request_field, diff --git a/tests/unittests/fapi_adaptor/mac/messages/CMakeLists.txt b/tests/unittests/fapi_adaptor/mac/messages/CMakeLists.txt index 1cbc62c0ed..f54b2568bd 100644 --- a/tests/unittests/fapi_adaptor/mac/messages/CMakeLists.txt +++ b/tests/unittests/fapi_adaptor/mac/messages/CMakeLists.txt @@ -31,3 +31,7 @@ gtest_discover_tests(mac_fapi_pucch_adaptor_test) add_executable(mac_fapi_pusch_adaptor_test ul_pusch_pdu_test.cpp) target_link_libraries(mac_fapi_pusch_adaptor_test srsran_mac_fapi_adaptors srsran_support srsran_fapi_uci_part2_tools gtest gtest_main srsran_mac_translator_helpers) gtest_discover_tests(mac_fapi_pusch_adaptor_test) + +add_executable(mac_fapi_srs_adaptor_test ul_srs_pdu_test.cpp) +target_link_libraries(mac_fapi_srs_adaptor_test srsran_mac_fapi_adaptors srsran_support gtest gtest_main srsran_mac_translator_helpers) +gtest_discover_tests(mac_fapi_srs_adaptor_test) diff --git a/tests/unittests/fapi_adaptor/mac/messages/helpers.cpp b/tests/unittests/fapi_adaptor/mac/messages/helpers.cpp index a84fb88221..34272eb43a 100644 --- a/tests/unittests/fapi_adaptor/mac/messages/helpers.cpp +++ b/tests/unittests/fapi_adaptor/mac/messages/helpers.cpp @@ -466,6 +466,35 @@ ul_sched_info_test_helper unittests::build_valid_pusch_pdu() return helper; } +srs_info_helper unittests::build_valid_srs_pdu() +{ + srs_info_helper helper; + + srs_info& pdu = helper.pdu; + helper.bwp_cfg = {cyclic_prefix::NORMAL, subcarrier_spacing::kHz15, {10, 20}}; + + pdu.crnti = to_rnti(23); + pdu.bwp_cfg = &helper.bwp_cfg; + pdu.nof_antenna_ports = 4; + pdu.symbols = {0, 1}; + pdu.nof_repetitions = n1; + pdu.config_index = 4; + pdu.sequence_id = 4; + pdu.bw_index = 2; + pdu.tx_comb = tx_comb_size::n2; + pdu.comb_offset = 2; + pdu.cyclic_shift = 2; + pdu.freq_position = 32; + pdu.freq_shift = 21; + pdu.freq_hopping = 12; + pdu.group_or_seq_hopping = srs_group_or_sequence_hopping::neither; + pdu.resource_type = srs_resource_type::aperiodic; + pdu.t_srs_period = srs_periodicity::sl8; + pdu.t_offset = 65; + + return helper; +} + pucch_info_test_helper unittests::build_valid_pucch_format_1_pdu() { pucch_info_test_helper helper; diff --git a/tests/unittests/fapi_adaptor/mac/messages/helpers.h b/tests/unittests/fapi_adaptor/mac/messages/helpers.h index 7d3252b6fb..6d39f48746 100644 --- a/tests/unittests/fapi_adaptor/mac/messages/helpers.h +++ b/tests/unittests/fapi_adaptor/mac/messages/helpers.h @@ -82,6 +82,14 @@ struct ul_sched_info_test_helper { /// Builds and returns a valid PUSCH PDU. ul_sched_info_test_helper build_valid_pusch_pdu(); +struct srs_info_helper { + bwp_configuration bwp_cfg; + srs_info pdu; +}; + +/// Builds and returns a valid SRS PDU. +srs_info_helper build_valid_srs_pdu(); + /// Helper struct to manage the pointer life cycle of a PUCCH info. struct pucch_info_test_helper { bwp_configuration bwp_cfg; diff --git a/tests/unittests/fapi_adaptor/mac/messages/ul_pusch_pdu_test.cpp b/tests/unittests/fapi_adaptor/mac/messages/ul_pusch_pdu_test.cpp index e123edd577..77994ebb5a 100644 --- a/tests/unittests/fapi_adaptor/mac/messages/ul_pusch_pdu_test.cpp +++ b/tests/unittests/fapi_adaptor/mac/messages/ul_pusch_pdu_test.cpp @@ -18,7 +18,7 @@ using namespace srsran; using namespace fapi_adaptor; using namespace unittests; -TEST(mac_to_fapi_pusch_pdu_test, valid_pusch_pdu_shoul_pass) +TEST(mac_to_fapi_pusch_pdu_test, valid_pusch_pdu_should_pass) { const ul_sched_info_test_helper& pdu_test = build_valid_pusch_pdu(); const ul_sched_info& mac_pdu = pdu_test.info; diff --git a/tests/unittests/fapi_adaptor/mac/messages/ul_srs_pdu_test.cpp b/tests/unittests/fapi_adaptor/mac/messages/ul_srs_pdu_test.cpp new file mode 100644 index 0000000000..be259bf0ad --- /dev/null +++ b/tests/unittests/fapi_adaptor/mac/messages/ul_srs_pdu_test.cpp @@ -0,0 +1,51 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "helpers.h" +#include "srsran/fapi_adaptor/mac/messages/srs.h" +#include + +using namespace srsran; +using namespace fapi_adaptor; +using namespace unittests; + +TEST(mac_to_fapi_srs_pdu_test, valid_srs_pdu_should_pass) +{ + const srs_info_helper& pdu_test = build_valid_srs_pdu(); + const srs_info& mac_pdu = pdu_test.pdu; + fapi::ul_srs_pdu fapi_pdu; + + convert_srs_mac_to_fapi(fapi_pdu, mac_pdu); + + ASSERT_EQ(mac_pdu.crnti, fapi_pdu.rnti); + + // BWP. + ASSERT_EQ(mac_pdu.bwp_cfg->cp, fapi_pdu.cp); + ASSERT_EQ(mac_pdu.bwp_cfg->scs, fapi_pdu.scs); + ASSERT_EQ(mac_pdu.bwp_cfg->crbs.start(), fapi_pdu.bwp_start); + ASSERT_EQ(mac_pdu.bwp_cfg->crbs.length(), fapi_pdu.bwp_size); + + ASSERT_EQ(mac_pdu.nof_antenna_ports, fapi_pdu.num_ant_ports); + ASSERT_EQ(mac_pdu.symbols.length(), fapi_pdu.num_symbols); + ASSERT_EQ(0, fapi_pdu.time_start_position); + ASSERT_EQ(mac_pdu.config_index, fapi_pdu.config_index); + ASSERT_EQ(mac_pdu.sequence_id, fapi_pdu.sequence_id); + ASSERT_EQ(mac_pdu.bw_index, fapi_pdu.bandwidth_index); + ASSERT_EQ(mac_pdu.tx_comb, fapi_pdu.comb_size); + ASSERT_EQ(mac_pdu.comb_offset, fapi_pdu.comb_offset); + ASSERT_EQ(mac_pdu.cyclic_shift, fapi_pdu.cyclic_shift); + ASSERT_EQ(mac_pdu.freq_position, fapi_pdu.frequency_position); + ASSERT_EQ(mac_pdu.freq_shift, fapi_pdu.frequency_shift); + ASSERT_EQ(mac_pdu.freq_hopping, fapi_pdu.frequency_hopping); + ASSERT_EQ(mac_pdu.group_or_seq_hopping, fapi_pdu.group_or_sequence_hopping); + ASSERT_EQ(mac_pdu.resource_type, fapi_pdu.resource_type); + ASSERT_EQ(mac_pdu.t_srs_period, fapi_pdu.t_srs); + ASSERT_EQ(mac_pdu.t_offset, fapi_pdu.t_offset); +} \ No newline at end of file From 54979fd1d717a6a41672509bde300a7d2d948cf0 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 12 Sep 2024 12:08:51 +0200 Subject: [PATCH 016/174] sched: fix PUCCH harq bit counter for format 0 Signed-off-by: Carlo Galiotto --- .../ue_scheduling/ue_scheduler_impl.cpp | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp index 0fd5443e8c..f1401f5abc 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp @@ -87,7 +87,8 @@ void ue_scheduler_impl::update_harq_pucch_counter(cell_resource_allocator& cell_ // Spans through the PUCCH grant list and update the HARQ-ACK PUCCH grant counter for the corresponding RNTI and HARQ // process id. for (const auto& pucch : slot_alloc.result.ul.pucchs) { - if ((pucch.format == pucch_format::FORMAT_1 and pucch.format_1.harq_ack_nof_bits > 0) or + if ((pucch.format == pucch_format::FORMAT_0 and pucch.format_0.harq_ack_nof_bits > 0) or + (pucch.format == pucch_format::FORMAT_1 and pucch.format_1.harq_ack_nof_bits > 0) or (pucch.format == pucch_format::FORMAT_2 and pucch.format_2.harq_ack_nof_bits > 0)) { ue* user = ue_db.find_by_rnti(pucch.crnti); // This is to handle the case of a UE that gets removed after the PUCCH gets allocated and before this PUCCH is @@ -99,11 +100,20 @@ void ue_scheduler_impl::update_harq_pucch_counter(cell_resource_allocator& cell_ slot_alloc.slot); continue; } - srsran_assert(pucch.format == pucch_format::FORMAT_1 or pucch.format == pucch_format::FORMAT_2, - "rnti={}: Only PUCCH format 1 and format 2 are supported", - pucch.crnti); - const unsigned nof_harqs_per_rnti_per_slot = - pucch.format == pucch_format::FORMAT_1 ? pucch.format_1.harq_ack_nof_bits : pucch.format_2.harq_ack_nof_bits; + unsigned nof_harqs_per_rnti_per_slot = 0; + switch (pucch.format) { + case pucch_format::FORMAT_0: + nof_harqs_per_rnti_per_slot = pucch.format_0.harq_ack_nof_bits; + break; + case pucch_format::FORMAT_1: + nof_harqs_per_rnti_per_slot = pucch.format_1.harq_ack_nof_bits; + break; + case pucch_format::FORMAT_2: + nof_harqs_per_rnti_per_slot = pucch.format_2.harq_ack_nof_bits; + break; + default: + srsran_assertion_failure("rnti={}: Only PUCCH format 0, 1 and 2 are supported", pucch.crnti); + } // Each PUCCH grants can potentially carry ACKs for different HARQ processes (as many as the harq_ack_nof_bits) // expecting to be acknowledged on the same slot. for (unsigned harq_bit_idx = 0; harq_bit_idx != nof_harqs_per_rnti_per_slot; ++harq_bit_idx) { From 11da60344011bb4f4a6e6e6a30a579fb0225f0fe Mon Sep 17 00:00:00 2001 From: asaezper Date: Fri, 13 Sep 2024 10:03:28 +0200 Subject: [PATCH 017/174] ci: change test mode ru dummy config --- tests/e2e/tests/test_mode/config_ru.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e/tests/test_mode/config_ru.yml b/tests/e2e/tests/test_mode/config_ru.yml index 5cad482059..a1e1943c2e 100644 --- a/tests/e2e/tests/test_mode/config_ru.yml +++ b/tests/e2e/tests/test_mode/config_ru.yml @@ -25,7 +25,6 @@ cell_cfg: pdsch: min_ue_mcs: 27 mcs_table: qam256 - max_rb_size: 16 pusch: min_ue_mcs: 27 mcs_table: qam256 From d6ae51d04ffab976ef550288d7ffe841b91a5c1f Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Thu, 12 Sep 2024 16:35:41 +0200 Subject: [PATCH 018/174] du: add the power controller interface that provides start/stop functionality. Use this interface in the DU interfaces. --- apps/du/du.cpp | 6 ++-- apps/gnb/gnb.cpp | 5 ++-- .../flexible_du/split_6/split6_du_impl.cpp | 4 +-- .../flexible_du/split_6/split6_du_impl.h | 6 +++- .../split_dynamic/dynamic_du_impl.cpp | 4 +-- .../split_dynamic/dynamic_du_impl.h | 6 +++- include/srsran/du/du.h | 10 +++---- include/srsran/du/du_high/du_high_wrapper.h | 9 ++++-- include/srsran/du/du_low/du_low.h | 5 ++-- include/srsran/du/du_power_controller.h | 28 +++++++++++++++++++ include/srsran/du/du_wrapper.h | 10 +++++-- lib/du/du_high/du_high_wrapper_impl.h | 6 +++- lib/du/du_low/du_low_impl.h | 9 +++++- lib/du/du_wrapper_impl.cpp | 6 ++-- lib/du/du_wrapper_impl.h | 7 +++-- 15 files changed, 92 insertions(+), 29 deletions(-) create mode 100644 include/srsran/du/du_power_controller.h diff --git a/apps/du/du.cpp b/apps/du/du.cpp index 0b1c8f78c8..dd9c189b24 100644 --- a/apps/du/du.cpp +++ b/apps/du/du.cpp @@ -56,6 +56,8 @@ #include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.h" #include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h" +#include "srsran/du/du_power_controller.h" + #ifdef DPDK_FOUND #include "srsran/hal/dpdk/dpdk_eal_factory.h" #endif @@ -324,7 +326,7 @@ int main(int argc, char** argv) app_services::stdin_command_dispatcher command_parser(*epoll_broker, du_inst_and_cmds.commands); // Start processing. - du_inst.start(); + du_inst.get_power_controller().start(); { app_services::application_message_banners app_banner(app_name); @@ -334,7 +336,7 @@ int main(int argc, char** argv) } // Stop DU activity. - du_inst.stop(); + du_inst.get_power_controller().stop(); if (du_cfg.e2_cfg.enable_du_e2) { du_logger.info("Closing E2 network connections..."); diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 03b49af8ae..1edfcb212a 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -72,6 +72,7 @@ #include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.h" #include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.h" #include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h" +#include "srsran/du/du_power_controller.h" #include "srsran/support/cli11_utils.h" #include @@ -460,7 +461,7 @@ int main(int argc, char** argv) cu_up_obj->start(); // Start processing. - du_inst.start(); + du_inst.get_power_controller().start(); { app_services::application_message_banners app_banner(app_name); @@ -471,7 +472,7 @@ int main(int argc, char** argv) } // Stop DU activity. - du_inst.stop(); + du_inst.get_power_controller().stop(); // Stop CU-UP activity. cu_up_obj->stop(); diff --git a/apps/units/flexible_du/split_6/split6_du_impl.cpp b/apps/units/flexible_du/split_6/split6_du_impl.cpp index 3f8a4c935b..4c5a9a4821 100644 --- a/apps/units/flexible_du/split_6/split6_du_impl.cpp +++ b/apps/units/flexible_du/split_6/split6_du_impl.cpp @@ -36,7 +36,7 @@ split6_du_impl::split6_du_impl(std::vector> void split6_du_impl::start() { for (auto& du_obj : du_list) { - du_obj->start(); + du_obj->get_power_controller().start(); } for (auto& adaptor : adaptors) { @@ -47,7 +47,7 @@ void split6_du_impl::start() void split6_du_impl::stop() { for (auto& du_obj : du_list) { - du_obj->stop(); + du_obj->get_power_controller().stop(); } for (auto& adaptor : adaptors) { diff --git a/apps/units/flexible_du/split_6/split6_du_impl.h b/apps/units/flexible_du/split_6/split6_du_impl.h index ae26d99a3c..8113f71ca8 100644 --- a/apps/units/flexible_du/split_6/split6_du_impl.h +++ b/apps/units/flexible_du/split_6/split6_du_impl.h @@ -12,6 +12,7 @@ #include "srsran/du/du.h" #include "srsran/du/du_high_wrapper.h" +#include "srsran/du/du_power_controller.h" #include "srsran/fapi_adaptor/fapi_adaptor.h" #include #include @@ -20,12 +21,15 @@ namespace srsran { class radio_unit; -class split6_du_impl : public du +class split6_du_impl : public srs_du::du, public du_power_controller { public: explicit split6_du_impl(std::vector> adaptors_, std::vector> du_list_); + // See interface for documentation. + du_power_controller& get_power_controller() override { return *this; } + // See interface for documentation. void start() override; diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp index ee85e46ee2..b35f4fea42 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp @@ -27,7 +27,7 @@ dynamic_du_impl::dynamic_du_impl(unsigned nof_cells) : void dynamic_du_impl::start() { for (auto& du_obj : du_list) { - du_obj->start(); + du_obj->get_power_controller().start(); } ru->get_controller().start(); @@ -38,7 +38,7 @@ void dynamic_du_impl::stop() ru->get_controller().stop(); for (auto& du_obj : du_list) { - du_obj->stop(); + du_obj->get_power_controller().stop(); } } diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h index 2f117116f4..1e16a8c5ec 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.h @@ -11,6 +11,7 @@ #pragma once #include "srsran/du/du.h" +#include "srsran/du/du_power_controller.h" #include "srsran/du/du_wrapper.h" #include "srsran/ru/ru_adapters.h" #include @@ -20,11 +21,14 @@ namespace srsran { class radio_unit; -class dynamic_du_impl : public srs_du::du +class dynamic_du_impl : public srs_du::du, public du_power_controller { public: explicit dynamic_du_impl(unsigned nof_cells); + // See interface for documentation. + du_power_controller& get_power_controller() override { return *this; } + // See interface for documentation. void start() override; diff --git a/include/srsran/du/du.h b/include/srsran/du/du.h index b965eb9426..2577e6a9c2 100644 --- a/include/srsran/du/du.h +++ b/include/srsran/du/du.h @@ -11,6 +11,9 @@ #pragma once namespace srsran { + +class du_power_controller; + namespace srs_du { /// Public DU interface. @@ -19,11 +22,8 @@ class du public: virtual ~du() = default; - /// Starts the DU. - virtual void start() = 0; - - /// Stops the DU. - virtual void stop() = 0; + /// Returns the power controller of this DU. + virtual du_power_controller& get_power_controller() = 0; }; } // namespace srs_du diff --git a/include/srsran/du/du_high/du_high_wrapper.h b/include/srsran/du/du_high/du_high_wrapper.h index 85b9750095..e977fd517d 100644 --- a/include/srsran/du/du_high/du_high_wrapper.h +++ b/include/srsran/du/du_high/du_high_wrapper.h @@ -10,10 +10,10 @@ #pragma once -#include "srsran/du/du.h" - namespace srsran { +class du_power_controller; + namespace fapi { class slot_data_message_notifier; class slot_error_message_notifier; @@ -25,11 +25,14 @@ namespace srs_du { class du_high; /// Distributed Unit high wrapper interface. Wraps a DU high with the MAC FAPI adaptor. -class du_high_wrapper : public du +class du_high_wrapper { public: virtual ~du_high_wrapper() = default; + /// Returns the power controller of this DU high wrapper. + virtual du_power_controller& get_power_controller() = 0; + /// Returns the DU high from this DU wrapper. virtual du_high& get_du_high() = 0; diff --git a/include/srsran/du/du_low/du_low.h b/include/srsran/du/du_low/du_low.h index 08211c4c1b..3720aae7a2 100644 --- a/include/srsran/du/du_low/du_low.h +++ b/include/srsran/du/du_low/du_low.h @@ -14,6 +14,7 @@ namespace srsran { +class du_power_controller; class upper_phy; namespace srs_du { @@ -25,8 +26,8 @@ class du_low /// Default destructor. virtual ~du_low() = default; - /// Stops the DU low. - virtual void stop() = 0; + /// Returns the power controller of this DU low. + virtual du_power_controller& get_power_controller() = 0; /// Returns the upper PHY for the given cell of this DU low. virtual upper_phy& get_upper_phy(unsigned cell_id) = 0; diff --git a/include/srsran/du/du_power_controller.h b/include/srsran/du/du_power_controller.h new file mode 100644 index 0000000000..bdfc18a794 --- /dev/null +++ b/include/srsran/du/du_power_controller.h @@ -0,0 +1,28 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +namespace srsran { + +/// DU power controller interface that allows to start/stop a DU. +class du_power_controller +{ +public: + virtual ~du_power_controller() = default; + + /// Starts the DU. + virtual void start() = 0; + + /// Stops the DU. + virtual void stop() = 0; +}; + +} // namespace srsran diff --git a/include/srsran/du/du_wrapper.h b/include/srsran/du/du_wrapper.h index c49dc5c6a9..6ae9b0ed17 100644 --- a/include/srsran/du/du_wrapper.h +++ b/include/srsran/du/du_wrapper.h @@ -13,17 +13,23 @@ #include "srsran/du/du.h" namespace srsran { + +class du_power_controller; + namespace srs_du { class du_high_wrapper; class du_low_wrapper; -/// Distributed Unit wrapper interface. Wraps the DU high wrapper and DU low wrapper in an object. -class du_wrapper : public du +/// Distributed Unit wrapper interface. Wraps the DU high wrapper, DU low wrapper and a power controller in an object. +class du_wrapper { public: virtual ~du_wrapper() = default; + /// Returns the power controller of this DU wrapper. + virtual du_power_controller& get_power_controller() = 0; + /// Returns the DU high wrapper of this DU wrapper. virtual du_high_wrapper& get_du_high_wrapper() = 0; diff --git a/lib/du/du_high/du_high_wrapper_impl.h b/lib/du/du_high/du_high_wrapper_impl.h index d8cdf3f2a9..216f48e518 100644 --- a/lib/du/du_high/du_high_wrapper_impl.h +++ b/lib/du/du_high/du_high_wrapper_impl.h @@ -12,6 +12,7 @@ #include "srsran/du/du_high/du_high.h" #include "srsran/du/du_high/du_high_wrapper.h" +#include "srsran/du/du_power_controller.h" #include "srsran/du/du_wrapper_config.h" #include "srsran/fapi_adaptor/mac/mac_fapi_adaptor.h" @@ -25,11 +26,14 @@ struct du_high_wrapper_impl_dependencies { }; /// DU high wrapper implementation. -class du_high_wrapper_impl : public du_high_wrapper +class du_high_wrapper_impl : public du_high_wrapper, public du_power_controller { public: explicit du_high_wrapper_impl(du_high_wrapper_impl_dependencies&& du_dependencies); + // See interface for documentation. + du_power_controller& get_power_controller() override { return *this; } + // See interface for documentation. void start() override; diff --git a/lib/du/du_low/du_low_impl.h b/lib/du/du_low/du_low_impl.h index 5526467efc..802e6eef5f 100644 --- a/lib/du/du_low/du_low_impl.h +++ b/lib/du/du_low/du_low_impl.h @@ -11,13 +11,14 @@ #pragma once #include "srsran/du/du_low/du_low.h" +#include "srsran/du/du_power_controller.h" #include "srsran/phy/upper/upper_phy.h" namespace srsran { namespace srs_du { /// DU low implementation. -class du_low_impl final : public du_low +class du_low_impl final : public du_low, public du_power_controller { public: explicit du_low_impl(std::vector> upper_); @@ -25,6 +26,12 @@ class du_low_impl final : public du_low // See interface for documentation. upper_phy& get_upper_phy(unsigned cell_id) override; + // See interface for documentation. + du_power_controller& get_power_controller() override { return *this; } + + // See interface for documentation. + void start() override{}; + // See interface for documentation. void stop() override; diff --git a/lib/du/du_wrapper_impl.cpp b/lib/du/du_wrapper_impl.cpp index 0fef8f927e..080e5c1ce6 100644 --- a/lib/du/du_wrapper_impl.cpp +++ b/lib/du/du_wrapper_impl.cpp @@ -25,13 +25,13 @@ du_wrapper_impl::du_wrapper_impl(du_wrapper_impl_dependencies&& dependencies) : void du_wrapper_impl::start() { - du_hi->start(); + du_hi->get_power_controller().start(); } void du_wrapper_impl::stop() { - du_lo->get_du_low().stop(); - du_hi->stop(); + du_lo->get_du_low().get_power_controller().stop(); + du_hi->get_power_controller().stop(); } du_high_wrapper& du_wrapper_impl::get_du_high_wrapper() diff --git a/lib/du/du_wrapper_impl.h b/lib/du/du_wrapper_impl.h index 8a6a5af4a6..cc61189b2c 100644 --- a/lib/du/du_wrapper_impl.h +++ b/lib/du/du_wrapper_impl.h @@ -12,8 +12,8 @@ #include "srsran/du/du_high/du_high_wrapper.h" #include "srsran/du/du_low/du_low_wrapper.h" +#include "srsran/du/du_power_controller.h" #include "srsran/du/du_wrapper.h" -#include "srsran/fapi_adaptor/phy/phy_fapi_adaptor.h" #include namespace srsran { @@ -26,11 +26,14 @@ struct du_wrapper_impl_dependencies { }; /// DU wrapper implementation. -class du_wrapper_impl final : public du_wrapper +class du_wrapper_impl final : public du_wrapper, public du_power_controller { public: explicit du_wrapper_impl(du_wrapper_impl_dependencies&& du_cfg); + // See interface for documentation. + du_power_controller& get_power_controller() override { return *this; } + // See interface for documentation. void start() override; From c4c7ef35eb9c9c0abcfbc4339557ac2dc1382ccd Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 28 Aug 2024 16:53:36 +0200 Subject: [PATCH 019/174] cu_cp: store plmn in the cu-cp ue context --- lib/cu_cp/du_processor/du_processor_impl.cpp | 6 ++++-- lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp | 15 +++++++++++++-- lib/cu_cp/ue_manager/cu_cp_ue_impl.h | 16 ++++++++++------ lib/cu_cp/ue_manager/ue_manager_impl.cpp | 17 ++++++++++------- lib/cu_cp/ue_manager/ue_manager_impl.h | 14 +++++++++++--- .../cu_cp/ue_manager/ue_manager_test.cpp | 9 ++++++--- 6 files changed, 54 insertions(+), 23 deletions(-) diff --git a/lib/cu_cp/du_processor/du_processor_impl.cpp b/lib/cu_cp/du_processor/du_processor_impl.cpp index 13398da92f..316636f179 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.cpp +++ b/lib/cu_cp/du_processor/du_processor_impl.cpp @@ -207,7 +207,8 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c if (ue_index == ue_index_t::invalid) { // Add new CU-CP UE - ue_index = ue_mng.add_ue(cfg.du_index, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index); + ue_index = ue_mng.add_ue( + cfg.du_index, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index, req.cgi.plmn_id); if (ue_index == ue_index_t::invalid) { logger.warning("CU-CP UE creation failed"); return make_unexpected(rrc_du_adapter.on_rrc_reject_required()); @@ -217,7 +218,8 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c /// NOTE: From this point on the UE exists in the UE manager and must be removed if any error occurs. } else { - ue = ue_mng.set_ue_du_context(ue_index, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index); + ue = ue_mng.set_ue_du_context( + ue_index, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index, req.cgi.plmn_id); if (ue == nullptr) { logger.warning("ue={}: Could not create UE context", ue_index); // A UE with the same PCI and RNTI already exists, so we don't remove it and only reject the new UE. diff --git a/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp b/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp index 97c9a37a17..b8e36a254d 100644 --- a/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp +++ b/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp @@ -21,7 +21,8 @@ cu_cp_ue::cu_cp_ue(ue_index_t ue_index_, std::optional du_id_, std::optional pci_, std::optional c_rnti_, - std::optional pcell_index_) : + std::optional pcell_index_, + std::optional plmn_) : ue_index(ue_index_), task_sched(std::move(task_sched_)), up_mng(up_cfg), @@ -44,6 +45,10 @@ cu_cp_ue::cu_cp_ue(ue_index_t ue_index_, pcell_index = pcell_index_.value(); } + if (plmn_.has_value()) { + ue_ctxt.plmn = plmn_.value(); + } + ue_ctxt.du_idx = du_index_; rrc_ue_cu_cp_ue_ev_notifier.connect_ue(*this); @@ -51,7 +56,11 @@ cu_cp_ue::cu_cp_ue(ue_index_t ue_index_, } /// \brief Update a UE with PCI and/or C-RNTI. -void cu_cp_ue::update_du_ue(gnb_du_id_t du_id_, pci_t pci_, rnti_t c_rnti_, du_cell_index_t pcell_index_) +void cu_cp_ue::update_du_ue(gnb_du_id_t du_id_, + pci_t pci_, + rnti_t c_rnti_, + du_cell_index_t pcell_index_, + plmn_identity plmn_) { if (du_id_ != gnb_du_id_t::invalid) { ue_ctxt.du_id = du_id_; @@ -68,6 +77,8 @@ void cu_cp_ue::update_du_ue(gnb_du_id_t du_id_, pci_t pci_, rnti_t c_rnti_, du_c if (pcell_index_ != du_cell_index_t::invalid) { pcell_index = pcell_index_; } + + ue_ctxt.plmn = plmn_; } /// \brief Set/update the measurement context of the UE. diff --git a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h index 9e19ee65ef..9fe22b79d1 100644 --- a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h +++ b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h @@ -17,6 +17,7 @@ #include "../up_resource_manager/up_resource_manager_impl.h" #include "cu_cp_ue_impl_interface.h" #include "ue_task_scheduler_impl.h" +#include "srsran/ran/plmn_identity.h" #include #include @@ -26,10 +27,11 @@ namespace srs_cu_cp { /// \brief Context of a CU-CP UE. struct cu_cp_ue_context { - du_index_t du_idx = du_index_t::invalid; - gnb_du_id_t du_id = gnb_du_id_t::invalid; - ue_index_t ue_index = ue_index_t::invalid; - rnti_t crnti = rnti_t::INVALID_RNTI; + du_index_t du_idx = du_index_t::invalid; + gnb_du_id_t du_id = gnb_du_id_t::invalid; + ue_index_t ue_index = ue_index_t::invalid; + rnti_t crnti = rnti_t::INVALID_RNTI; + plmn_identity plmn = plmn_identity::test_value(); /// \brief Flag to disable new UE reconfigurations. This can be used, for instance, to reconfigure UE contexts /// that are in the process of handover. bool reconfiguration_disabled = false; @@ -46,7 +48,8 @@ class cu_cp_ue : public cu_cp_ue_impl_interface std::optional du_id_ = std::nullopt, std::optional pci_ = std::nullopt, std::optional c_rnti_ = std::nullopt, - std::optional pcell_index_ = std::nullopt); + std::optional pcell_index_ = std::nullopt, + std::optional plmn_ = std::nullopt); /// \brief Cancel all pending UE tasks. void stop(); @@ -87,7 +90,8 @@ class cu_cp_ue : public cu_cp_ue_impl_interface void update_du_ue(gnb_du_id_t du_id_ = gnb_du_id_t::invalid, pci_t pci_ = INVALID_PCI, rnti_t c_rnti_ = rnti_t::INVALID_RNTI, - du_cell_index_t pcell_index_ = du_cell_index_t::invalid); + du_cell_index_t pcell_index_ = du_cell_index_t::invalid, + plmn_identity plmn_ = plmn_identity::test_value()); /// \brief Set/update the measurement context of the UE. void update_meas_context(cell_meas_manager_ue_context meas_ctxt); diff --git a/lib/cu_cp/ue_manager/ue_manager_impl.cpp b/lib/cu_cp/ue_manager/ue_manager_impl.cpp index 7d9a1de16e..723bf50d85 100644 --- a/lib/cu_cp/ue_manager/ue_manager_impl.cpp +++ b/lib/cu_cp/ue_manager/ue_manager_impl.cpp @@ -37,7 +37,8 @@ ue_index_t ue_manager::add_ue(du_index_t du_index, std::optional du_id, std::optional pci, std::optional rnti, - std::optional pcell_index) + std::optional pcell_index, + std::optional plmn) { if (du_index == du_index_t::invalid) { logger.warning("CU-CP UE creation Failed. Cause: Invalid DU index={}", du_index); @@ -85,10 +86,11 @@ ue_index_t ue_manager::add_ue(du_index_t du_index, ue_task_scheduler_impl ue_sched = ue_task_scheds.create_ue_task_sched(new_ue_index); // Create UE object - ues.emplace(std::piecewise_construct, - std::forward_as_tuple(new_ue_index), - std::forward_as_tuple( - new_ue_index, du_index, up_config, sec_config, std::move(ue_sched), du_id, pci, rnti, pcell_index)); + ues.emplace( + std::piecewise_construct, + std::forward_as_tuple(new_ue_index), + std::forward_as_tuple( + new_ue_index, du_index, up_config, sec_config, std::move(ue_sched), du_id, pci, rnti, pcell_index, plmn)); // Add PCI and RNTI to lookup. if (pci.has_value() && rnti.has_value()) { @@ -169,7 +171,8 @@ cu_cp_ue* ue_manager::set_ue_du_context(ue_index_t ue_index, gnb_du_id_t du_id, pci_t pci, rnti_t rnti, - du_cell_index_t pcell_index) + du_cell_index_t pcell_index, + plmn_identity plmn) { srsran_assert(ue_index != ue_index_t::invalid, "Invalid ue_index={}", ue_index); srsran_assert(pci != INVALID_PCI, "Invalid pci={}", pci); @@ -189,7 +192,7 @@ cu_cp_ue* ue_manager::set_ue_du_context(ue_index_t ue_index, } auto& ue = ues.at(ue_index); - ue.update_du_ue(du_id, pci, rnti, pcell_index); + ue.update_du_ue(du_id, pci, rnti, pcell_index, plmn); // Add PCI and RNTI to lookup. pci_rnti_to_ue_index.emplace(std::make_tuple(pci, rnti), ue_index); diff --git a/lib/cu_cp/ue_manager/ue_manager_impl.h b/lib/cu_cp/ue_manager/ue_manager_impl.h index deb7bd67a4..0cf8eba0c1 100644 --- a/lib/cu_cp/ue_manager/ue_manager_impl.h +++ b/lib/cu_cp/ue_manager/ue_manager_impl.h @@ -19,6 +19,7 @@ #include "srsran/cu_cp/cu_cp_configuration.h" #include "srsran/cu_cp/security_manager_config.h" #include "srsran/cu_cp/ue_configuration.h" +#include "srsran/ran/plmn_identity.h" #include #include @@ -71,12 +72,14 @@ class ue_manager : public ue_metrics_handler /// \param[in] pci The PCI of the cell the UE is connected to. /// \param[in] rnti The RNTI of the UE. /// \param[in] pcell_index The index of the PCell the UE is connected to. + /// \param[in] plmn The PLMN of the UE. /// \return ue_index of the created UE or ue_index_t::invalid in case of failure. ue_index_t add_ue(du_index_t du_index, std::optional du_id = std::nullopt, std::optional pci = std::nullopt, std::optional rnti = std::nullopt, - std::optional pcell_index = std::nullopt); + std::optional pcell_index = std::nullopt, + std::optional plmn = std::nullopt); /// \brief Set the DU context of the UE. /// \param[in] ue_index Index of the UE. @@ -84,9 +87,14 @@ class ue_manager : public ue_metrics_handler /// \param[in] pci The PCI of the cell the UE is connected to. /// \param[in] rnti The RNTI of the UE. /// \param[in] pcell_index The index of the PCell the UE is connected to. + /// \param[in] plmn The PLMN of the UE. /// \return Pointer to the DU UE if found, nullptr otherwise. - cu_cp_ue* - set_ue_du_context(ue_index_t ue_index, gnb_du_id_t du_id, pci_t pci, rnti_t rnti, du_cell_index_t pcell_index); + cu_cp_ue* set_ue_du_context(ue_index_t ue_index, + gnb_du_id_t du_id, + pci_t pci, + rnti_t rnti, + du_cell_index_t pcell_index, + plmn_identity plmn); /// \brief Find the UE with the given UE index, thats DU context is set up. /// \param[in] ue_index Index of the UE to be found. diff --git a/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp b/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp index f9522a117b..7c668fda67 100644 --- a/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp +++ b/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp @@ -9,6 +9,7 @@ */ #include "ue_manager_test_helpers.h" +#include "srsran/ran/plmn_identity.h" #include using namespace srsran; @@ -97,8 +98,9 @@ TEST_F(ue_manager_test, when_du_context_valid_then_ue_updated) ue_index_t ue_index = ue_mng.add_ue(du_index); rnti_t rnti = to_rnti(0x4601); du_cell_index_t pcell_index = du_cell_index_t::min; + plmn_identity plmn = plmn_identity::test_value(); - auto* ue = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + auto* ue = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index, plmn); // check that the UE has been created ASSERT_NE(ue, nullptr); @@ -148,12 +150,13 @@ TEST_F(ue_manager_test, when_rnti_already_exits_then_ue_not_added) du_index_t du_index = du_index_t::min; rnti_t rnti = to_rnti(0x4601); du_cell_index_t pcell_index = du_cell_index_t::min; - ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + plmn_identity plmn = plmn_identity::test_value(); + ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index, plmn); // check that the number of DU UEs is 1 ASSERT_EQ(ue_mng.get_nof_du_ues(du_index), 1U); - auto* ue2 = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + auto* ue2 = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index, plmn); // check that the UE has not been added ASSERT_EQ(ue2, nullptr); From 1baef82e12eaf55e824289b621ecc5ce449ff103 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 30 Aug 2024 15:55:36 +0200 Subject: [PATCH 020/174] cu_cp,ngap: generate ng setup request in ngap based on configuration --- include/srsran/cu_cp/cu_cp_types.h | 17 +++++++ include/srsran/ngap/ngap.h | 4 +- include/srsran/ngap/ngap_setup.h | 11 ---- .../amf_connection_manager.cpp | 9 ++-- .../cu_cp_controller/amf_connection_manager.h | 9 ++-- .../cu_cp_controller/cu_cp_controller.cpp | 2 +- .../routines/amf_connection_setup_routine.cpp | 50 ++----------------- .../routines/amf_connection_setup_routine.h | 6 +-- lib/ngap/ngap_asn1_helpers.h | 41 ++++++++------- lib/ngap/ngap_context.h | 1 + lib/ngap/ngap_impl.cpp | 7 +-- lib/ngap/ngap_impl.h | 2 +- .../ngap/ngap_integration_test.cpp | 46 +---------------- .../ngap/ng_setup_procedure_test.cpp | 17 +++---- .../unittests/ngap/ngap_asn1_packer_test.cpp | 4 +- tests/unittests/ngap/ngap_test_messages.cpp | 28 ----------- tests/unittests/ngap/ngap_test_messages.h | 3 -- 17 files changed, 69 insertions(+), 188 deletions(-) diff --git a/include/srsran/cu_cp/cu_cp_types.h b/include/srsran/cu_cp/cu_cp_types.h index 18b5d6bd40..764c344943 100644 --- a/include/srsran/cu_cp/cu_cp_types.h +++ b/include/srsran/cu_cp/cu_cp_types.h @@ -42,6 +42,8 @@ const uint16_t MAX_NOF_DU_CELLS = 16; const uint16_t MAX_NOF_CU_UPS = 65535; /// Maximum number of UEs supported by CU-CP (implementation-defined). const uint64_t MAX_NOF_CU_UES = 4294967295; // 2^32 - 1 +/// Maximum number of AMFs supported by CU-CP (implementation-defined). +const uint16_t MAX_NOF_AMFS = 65535; /// \brief ue_index internally used to identify the UE CU-CP-wide. /// \remark The ue_index is derived from the maximum number of DUs and the maximum number of UEs per DU. @@ -104,6 +106,21 @@ constexpr inline std::underlying_type_t du_cell_index_to_uint(d return static_cast>(du_cell_index); } +/// Maximum number of AMFs supported by CU-CP (implementation-defined). +enum class amf_index_t : uint16_t { min = 0, max = MAX_NOF_AMFS - 1, invalid = MAX_NOF_AMFS }; + +/// Convert integer to AMF index type. +constexpr inline amf_index_t uint_to_amf_index(std::underlying_type_t index) +{ + return static_cast(index); +} + +/// Convert AMF index type to integer. +constexpr inline std::underlying_type_t amf_index_to_uint(amf_index_t amf_index) +{ + return static_cast>(amf_index); +} + /// QoS Configuration, i.e. 5QI and the associated PDCP /// and SDAP configuration for DRBs struct cu_cp_qos_config { diff --git a/include/srsran/ngap/ngap.h b/include/srsran/ngap/ngap.h index b32fdc3074..0db0afd693 100644 --- a/include/srsran/ngap/ngap.h +++ b/include/srsran/ngap/ngap.h @@ -65,11 +65,11 @@ class ngap_connection_manager virtual async_task handle_amf_disconnection_request() = 0; /// \brief Initiates the NG Setup procedure. - /// \param[in] request The NGSetupRequest message to transmit. + /// \param[in] max_setup_retries The maximum number of setup retries. /// \return Returns a ngap_ng_setup_result struct. /// \remark The CU transmits the NGSetupRequest as per TS 38.413 section 8.7.1 /// and awaits the response. If a NGSetupFailure is received the NGAP will handle the failure. - virtual async_task handle_ng_setup_request(const ngap_ng_setup_request& request) = 0; + virtual async_task handle_ng_setup_request(unsigned max_setup_retries) = 0; /// \brief Initiates NG Reset procedure as per TS 38.413 section 8.7.4.2.2. /// \param[in] msg The ng reset message to transmit. diff --git a/include/srsran/ngap/ngap_setup.h b/include/srsran/ngap/ngap_setup.h index de16ce3b51..67fb971999 100644 --- a/include/srsran/ngap/ngap_setup.h +++ b/include/srsran/ngap/ngap_setup.h @@ -30,17 +30,6 @@ struct ngap_supported_ta_item { std::vector broadcast_plmn_list; }; -struct ngap_ng_setup_request { - unsigned max_setup_retries = 1; - cu_cp_global_gnb_id global_ran_node_id; - std::string ran_node_name; - std::vector supported_ta_list; - uint16_t default_paging_drx; - // TODO: Add optional ue_retention_info; - // TODO: Add optional nb_iot_default_paging_drx - // TODO: Add optional extended_ran_node_name -}; - struct ngap_served_guami_item { guami_t guami; std::optional backup_amf_name; diff --git a/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp b/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp index c04fb65549..3f6da23ac8 100644 --- a/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp +++ b/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp @@ -16,10 +16,9 @@ using namespace srsran; using namespace srs_cu_cp; -amf_connection_manager::amf_connection_manager(common_task_scheduler& common_task_sched_, - const cu_cp_configuration& cu_cp_cfg_, - ngap_connection_manager& ngap_conn_mng_) : - common_task_sched(common_task_sched_), cu_cp_cfg(cu_cp_cfg_), ngap_conn_mng(ngap_conn_mng_) +amf_connection_manager::amf_connection_manager(common_task_scheduler& common_task_sched_, + ngap_connection_manager& ngap_conn_mng_) : + common_task_sched(common_task_sched_), ngap_conn_mng(ngap_conn_mng_) { } @@ -31,7 +30,7 @@ void amf_connection_manager::connect_to_amf(std::promise* completion_signa CORO_BEGIN(ctx); // Launch procedure to initiate AMF connection. - CORO_AWAIT_VALUE(bool success, launch_async(cu_cp_cfg, ngap_conn_mng)); + CORO_AWAIT_VALUE(bool success, launch_async(ngap_conn_mng)); // Handle result of NG setup. handle_connection_setup_result(success); diff --git a/lib/cu_cp/cu_cp_controller/amf_connection_manager.h b/lib/cu_cp/cu_cp_controller/amf_connection_manager.h index 00b9d4662c..dbc1588c4d 100644 --- a/lib/cu_cp/cu_cp_controller/amf_connection_manager.h +++ b/lib/cu_cp/cu_cp_controller/amf_connection_manager.h @@ -23,9 +23,7 @@ struct cu_cp_configuration; class amf_connection_manager { public: - amf_connection_manager(common_task_scheduler& common_task_sched_, - const cu_cp_configuration& cu_cp_cfg_, - ngap_connection_manager& ngap_conn_mng_); + amf_connection_manager(common_task_scheduler& common_task_sched_, ngap_connection_manager& ngap_conn_mng_); /// \brief Initiates the connection to the AMF. /// A promise is passed as a parameter to enable blocking synchronization between the completion of the scheduled @@ -41,9 +39,8 @@ class amf_connection_manager private: void handle_connection_setup_result(bool success); - common_task_scheduler& common_task_sched; - const cu_cp_configuration& cu_cp_cfg; - ngap_connection_manager& ngap_conn_mng; + common_task_scheduler& common_task_sched; + ngap_connection_manager& ngap_conn_mng; std::atomic amf_connected{false}; }; diff --git a/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp b/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp index b038bd4bfc..5a34350be4 100644 --- a/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp +++ b/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp @@ -26,7 +26,7 @@ cu_cp_controller::cu_cp_controller(const cu_cp_configuration& config_, common_task_sched(common_task_sched_), ctrl_exec(ctrl_exec_), logger(srslog::fetch_basic_logger("CU-CP")), - amf_mng(common_task_sched_, cfg, ngap_conn_mng_), + amf_mng(common_task_sched_, ngap_conn_mng_), du_mng(cfg.admission.max_nof_dus, dus_, ctrl_exec, common_task_sched_), cu_up_mng(cfg.admission.max_nof_cu_ups, cu_ups_, ctrl_exec, common_task_sched_) { diff --git a/lib/cu_cp/routines/amf_connection_setup_routine.cpp b/lib/cu_cp/routines/amf_connection_setup_routine.cpp index 6ae7804ed0..a5013b0e32 100644 --- a/lib/cu_cp/routines/amf_connection_setup_routine.cpp +++ b/lib/cu_cp/routines/amf_connection_setup_routine.cpp @@ -14,9 +14,8 @@ using namespace srsran; using namespace srs_cu_cp; -amf_connection_setup_routine::amf_connection_setup_routine(const cu_cp_configuration& cu_cp_cfg_, - ngap_connection_manager& ngap_conn_mng_) : - cu_cp_cfg(cu_cp_cfg_), ngap_conn_mng(ngap_conn_mng_) +amf_connection_setup_routine::amf_connection_setup_routine(ngap_connection_manager& ngap_conn_mng_) : + ngap_conn_mng(ngap_conn_mng_) { } @@ -34,51 +33,8 @@ void amf_connection_setup_routine::operator()(coro_context>& ct CORO_RETURN(std::holds_alternative(result_msg)); } -ngap_ng_setup_request amf_connection_setup_routine::fill_ng_setup_request() -{ - ngap_ng_setup_request request; - - // fill global ran node id - request.global_ran_node_id.gnb_id = cu_cp_cfg.node.gnb_id; - // TODO: Which PLMN do we need to use here? - request.global_ran_node_id.plmn_id = cu_cp_cfg.node.supported_tas.front().plmn; - // fill ran node name - request.ran_node_name = cu_cp_cfg.node.ran_node_name; - // fill supported ta list - for (const auto& supported_ta : cu_cp_cfg.node.supported_tas) { - // TODO: add support for more items - ngap_supported_ta_item supported_ta_item; - - ngap_broadcast_plmn_item broadcast_plmn_item; - broadcast_plmn_item.plmn_id = supported_ta.plmn; - - for (const auto& slice_config : supported_ta.supported_slices) { - slice_support_item_t slice_support_item; - slice_support_item.s_nssai.sst = slice_config.sst; - if (slice_config.sd.has_value()) { - slice_support_item.s_nssai.sd = slice_config.sd.value(); - } - broadcast_plmn_item.tai_slice_support_list.push_back(slice_support_item); - } - - supported_ta_item.broadcast_plmn_list.push_back(broadcast_plmn_item); - supported_ta_item.tac = supported_ta.tac; - - request.supported_ta_list.push_back(supported_ta_item); - } - - // fill paging drx - request.default_paging_drx = 256; - - return request; -} - async_task amf_connection_setup_routine::send_ng_setup_request() { - // Prepare request to send to ng. - ngap_ng_setup_request request = fill_ng_setup_request(); - request.max_setup_retries = 1; - // Initiate NG Setup Request. - return ngap_conn_mng.handle_ng_setup_request(request); + return ngap_conn_mng.handle_ng_setup_request(/*max_setup_retries*/ 1); } diff --git a/lib/cu_cp/routines/amf_connection_setup_routine.h b/lib/cu_cp/routines/amf_connection_setup_routine.h index 684ae70fae..f3765d8b2a 100644 --- a/lib/cu_cp/routines/amf_connection_setup_routine.h +++ b/lib/cu_cp/routines/amf_connection_setup_routine.h @@ -22,16 +22,14 @@ namespace srs_cu_cp { class amf_connection_setup_routine { public: - amf_connection_setup_routine(const cu_cp_configuration& cu_cp_cfg_, ngap_connection_manager& ngap_conn_mng_); + amf_connection_setup_routine(ngap_connection_manager& ngap_conn_mng_); void operator()(coro_context>& ctx); private: - ngap_ng_setup_request fill_ng_setup_request(); async_task send_ng_setup_request(); - const cu_cp_configuration& cu_cp_cfg; - ngap_connection_manager& ngap_conn_mng; + ngap_connection_manager& ngap_conn_mng; ngap_ng_setup_result result_msg = {}; }; diff --git a/lib/ngap/ngap_asn1_helpers.h b/lib/ngap/ngap_asn1_helpers.h index a4654cecdf..ad206c582b 100644 --- a/lib/ngap/ngap_asn1_helpers.h +++ b/lib/ngap/ngap_asn1_helpers.h @@ -35,50 +35,49 @@ namespace srs_cu_cp { /// \brief Fills ASN.1 NGSetupRequest struct. /// \param[out] asn1_request The NGSetupRequest ASN.1 struct to fill. -/// \param[in] request The common type NGSetupRequest. -inline void fill_asn1_ng_setup_request(asn1::ngap::ng_setup_request_s& asn1_request, - const ngap_ng_setup_request& request) +/// \param[in] ngap_ctxt The NGAP context. +inline void fill_asn1_ng_setup_request(asn1::ngap::ng_setup_request_s& asn1_request, const ngap_context_t& ngap_ctxt) { // fill global ran node id auto& global_gnb = asn1_request->global_ran_node_id.set_global_gnb_id(); global_gnb.gnb_id.set_gnb_id(); - global_gnb.gnb_id.gnb_id().from_number(request.global_ran_node_id.gnb_id.id, - request.global_ran_node_id.gnb_id.bit_length); - global_gnb.plmn_id = request.global_ran_node_id.plmn_id.to_bytes(); + global_gnb.gnb_id.gnb_id().from_number(ngap_ctxt.gnb_id.id, ngap_ctxt.gnb_id.bit_length); + // TODO: Which PLMN do we need to use here? + global_gnb.plmn_id = ngap_ctxt.supported_tas.front().plmn.to_bytes(); // fill ran node name asn1_request->ran_node_name_present = true; - asn1_request->ran_node_name.from_string(request.ran_node_name); + asn1_request->ran_node_name.from_string(ngap_ctxt.ran_node_name); // fill supported ta list - for (const auto& supported_ta_item : request.supported_ta_list) { + for (const auto& supported_ta_item : ngap_ctxt.supported_tas) { asn1::ngap::supported_ta_item_s asn1_supported_ta_item = {}; // fill tac asn1_supported_ta_item.tac.from_number(supported_ta_item.tac); // fill broadcast plmn list - for (const auto& broadcast_plmn_item : supported_ta_item.broadcast_plmn_list) { - asn1::ngap::broadcast_plmn_item_s asn1_broadcast_plmn_item = {}; + // TODO: add support for multiple plmn per ta + asn1::ngap::broadcast_plmn_item_s asn1_broadcast_plmn_item = {}; - // fill plmn id - asn1_broadcast_plmn_item.plmn_id = broadcast_plmn_item.plmn_id.to_bytes(); + // fill plmn id + asn1_broadcast_plmn_item.plmn_id = supported_ta_item.plmn.to_bytes(); - // fill tai slice support list - for (const auto& slice_support_item : broadcast_plmn_item.tai_slice_support_list) { - // fill s_nssai - asn1::ngap::slice_support_item_s asn1_slice_support_item = {}; - asn1_slice_support_item.s_nssai = s_nssai_to_asn1(slice_support_item.s_nssai); + // fill tai slice support list + for (const auto& slice_support_item : supported_ta_item.supported_slices) { + // fill s_nssai + asn1::ngap::slice_support_item_s asn1_slice_support_item = {}; + asn1_slice_support_item.s_nssai = s_nssai_to_asn1(slice_support_item); - asn1_broadcast_plmn_item.tai_slice_support_list.push_back(asn1_slice_support_item); - } - asn1_supported_ta_item.broadcast_plmn_list.push_back(asn1_broadcast_plmn_item); + asn1_broadcast_plmn_item.tai_slice_support_list.push_back(asn1_slice_support_item); } + asn1_supported_ta_item.broadcast_plmn_list.push_back(asn1_broadcast_plmn_item); + asn1_request->supported_ta_list.push_back(asn1_supported_ta_item); } // fill paging drx - asn1::number_to_enum(asn1_request->default_paging_drx, request.default_paging_drx); + asn1::number_to_enum(asn1_request->default_paging_drx, ngap_ctxt.default_paging_drx); } /// \brief Fills the common type \c ngap_ng_setup_result struct. diff --git a/lib/ngap/ngap_context.h b/lib/ngap/ngap_context.h index bb7602b3e9..3761c68b32 100644 --- a/lib/ngap/ngap_context.h +++ b/lib/ngap/ngap_context.h @@ -27,6 +27,7 @@ struct ngap_context_t { std::string ran_node_name; std::vector supported_tas; std::vector served_guami_list; + uint16_t default_paging_drx = 256; // default paging drx std::chrono::seconds pdu_session_setup_timeout; // timeout for PDU context setup in seconds }; diff --git a/lib/ngap/ngap_impl.cpp b/lib/ngap/ngap_impl.cpp index 69f591c8cd..cab14b8c40 100644 --- a/lib/ngap/ngap_impl.cpp +++ b/lib/ngap/ngap_impl.cpp @@ -25,6 +25,7 @@ #include "procedures/ngap_ue_context_release_procedure.h" #include "srsran/asn1/ngap/common.h" #include "srsran/ngap/ngap_reset.h" +#include "srsran/ngap/ngap_setup.h" #include "srsran/ngap/ngap_types.h" #include "srsran/ran/cause/ngap_cause.h" @@ -95,7 +96,7 @@ async_task ngap_impl::handle_amf_disconnection_request() return conn_handler.handle_tnl_association_removal(); } -async_task ngap_impl::handle_ng_setup_request(const ngap_ng_setup_request& request) +async_task ngap_impl::handle_ng_setup_request(unsigned max_setup_retries) { logger.info("Sending NgSetupRequest"); @@ -104,10 +105,10 @@ async_task ngap_impl::handle_ng_setup_request(const ngap_n ngap_msg.pdu.init_msg().load_info_obj(ASN1_NGAP_ID_NG_SETUP); auto& ng_setup_request = ngap_msg.pdu.init_msg().value.ng_setup_request(); - fill_asn1_ng_setup_request(ng_setup_request, request); + fill_asn1_ng_setup_request(ng_setup_request, context); return launch_async( - context, ngap_msg, request.max_setup_retries, *tx_pdu_notifier, ev_mng, timer_factory{timers, ctrl_exec}, logger); + context, ngap_msg, max_setup_retries, *tx_pdu_notifier, ev_mng, timer_factory{timers, ctrl_exec}, logger); } async_task ngap_impl::handle_ng_reset_message(const cu_cp_ng_reset& msg) diff --git a/lib/ngap/ngap_impl.h b/lib/ngap/ngap_impl.h index 56d8f20443..7d523ec9b4 100644 --- a/lib/ngap/ngap_impl.h +++ b/lib/ngap/ngap_impl.h @@ -43,7 +43,7 @@ class ngap_impl final : public ngap_interface // ngap connection manager functions bool handle_amf_tnl_connection_request() override; async_task handle_amf_disconnection_request() override; - async_task handle_ng_setup_request(const ngap_ng_setup_request& request) override; + async_task handle_ng_setup_request(unsigned max_setup_retries) override; async_task handle_ng_reset_message(const cu_cp_ng_reset& msg) override; // ngap_nas_message_handler diff --git a/tests/integrationtests/ngap/ngap_integration_test.cpp b/tests/integrationtests/ngap/ngap_integration_test.cpp index 390266d675..215cd65688 100644 --- a/tests/integrationtests/ngap/ngap_integration_test.cpp +++ b/tests/integrationtests/ngap/ngap_integration_test.cpp @@ -151,55 +151,11 @@ class ngap_integration_test : public ::testing::Test srslog::basic_logger& test_logger = srslog::fetch_basic_logger("TEST"); }; -ngap_ng_setup_request generate_ng_setup_request(const ngap_configuration& ngap_cfg) -{ - ngap_ng_setup_request request_msg = {}; - - ngap_ng_setup_request request; - - // fill global ran node id - request.global_ran_node_id.gnb_id = ngap_cfg.gnb_id; - // TODO: Which PLMN do we need to use here? - request.global_ran_node_id.plmn_id = ngap_cfg.supported_tas.front().plmn; - // fill ran node name - request.ran_node_name = ngap_cfg.ran_node_name; - // fill supported ta list - for (const auto& supported_ta : ngap_cfg.supported_tas) { - ngap_supported_ta_item supported_ta_item; - - supported_ta_item.tac = supported_ta.tac; - - ngap_broadcast_plmn_item broadcast_plmn_item; - broadcast_plmn_item.plmn_id = supported_ta.plmn; - - for (const auto& slice_config : supported_ta.supported_slices) { - slice_support_item_t slice_support_item; - slice_support_item.s_nssai.sst = slice_config.sst; - if (slice_config.sd.has_value()) { - slice_support_item.s_nssai.sd = slice_config.sd.value(); - } - broadcast_plmn_item.tai_slice_support_list.push_back(slice_support_item); - } - - supported_ta_item.broadcast_plmn_list.push_back(broadcast_plmn_item); - - request.supported_ta_list.push_back(supported_ta_item); - } - - // fill paging drx - request.default_paging_drx = 256; - - return request_msg; -} - /// Test successful ng setup procedure TEST_F(ngap_integration_test, when_ng_setup_response_received_then_amf_connected) { - // Action 1: Launch NG setup procedure - ngap_ng_setup_request request_msg = generate_ng_setup_request(cfg); - test_logger.info("Launching NG setup procedure..."); - async_task t = ngap->handle_ng_setup_request(request_msg); + async_task t = ngap->handle_ng_setup_request(1); lazy_task_launcher t_launcher(t); // Status: Procedure not yet ready. diff --git a/tests/unittests/ngap/ng_setup_procedure_test.cpp b/tests/unittests/ngap/ng_setup_procedure_test.cpp index c0ba377ef2..e95c897e82 100644 --- a/tests/unittests/ngap/ng_setup_procedure_test.cpp +++ b/tests/unittests/ngap/ng_setup_procedure_test.cpp @@ -20,9 +20,8 @@ using namespace srs_cu_cp; TEST_F(ngap_test, when_ng_setup_response_received_then_amf_connected) { // Action 1: Launch NG setup procedure - ngap_ng_setup_request request_msg = generate_ng_setup_request(); test_logger.info("Launch ng setup request procedure..."); - async_task t = ngap->handle_ng_setup_request(request_msg); + async_task t = ngap->handle_ng_setup_request(1); lazy_task_launcher t_launcher(t); // Status: AMF received NG Setup Request. @@ -47,9 +46,8 @@ TEST_F(ngap_test, when_ng_setup_response_received_then_amf_connected) TEST_F(ngap_test, when_ng_setup_failure_with_time_to_wait_received_then_retry_with_success) { // Action 1: Launch NG setup procedure - ngap_ng_setup_request request_msg = generate_ng_setup_request(); test_logger.info("Launch ng setup request procedure..."); - async_task t = ngap->handle_ng_setup_request(request_msg); + async_task t = ngap->handle_ng_setup_request(1); lazy_task_launcher t_launcher(t); // Status: AMF received NG Setup Request. @@ -90,9 +88,8 @@ TEST_F(ngap_test, when_ng_setup_failure_with_time_to_wait_received_then_retry_wi TEST_F(ngap_test, when_ng_setup_failure_with_time_to_wait_received_then_retry_without_success) { // Action 1: Launch NG setup procedure - ngap_ng_setup_request request_msg = generate_ng_setup_request(); test_logger.info("Launch ng setup request procedure..."); - async_task t = ngap->handle_ng_setup_request(request_msg); + async_task t = ngap->handle_ng_setup_request(1); lazy_task_launcher t_launcher(t); // Status: AMF received NG Setup Request. @@ -132,9 +129,9 @@ TEST_F(ngap_test, when_ng_setup_failure_with_time_to_wait_received_then_retry_wi TEST_F(ngap_test, when_retry_limit_reached_then_amf_not_connected) { // Action 1: Launch NG setup procedure - ngap_ng_setup_request request_msg = generate_ng_setup_request(); - test_logger.info("Launch f1 setup request procedure..."); - async_task t = ngap->handle_ng_setup_request(request_msg); + test_logger.info("Launch ng setup request procedure..."); + unsigned max_setup_retries = 1; + async_task t = ngap->handle_ng_setup_request(max_setup_retries); lazy_task_launcher t_launcher(t); // Status: AMF received NG Setup Request. @@ -146,7 +143,7 @@ TEST_F(ngap_test, when_retry_limit_reached_then_amf_not_connected) ngap_message ng_setup_response_msg = generate_ng_setup_failure_with_time_to_wait(asn1::ngap::time_to_wait_opts::v10s); ngap->handle_message(ng_setup_response_msg); - for (unsigned i = 0; i < request_msg.max_setup_retries; i++) { + for (unsigned i = 0; i < max_setup_retries; i++) { // Status: AMF does not receive new NG Setup Request until time-to-wait has ended. for (unsigned msec_elapsed = 0; msec_elapsed < 10000; ++msec_elapsed) { ASSERT_FALSE(t.ready()); diff --git a/tests/unittests/ngap/ngap_asn1_packer_test.cpp b/tests/unittests/ngap/ngap_asn1_packer_test.cpp index 86b97af757..a16b6bba8c 100644 --- a/tests/unittests/ngap/ngap_asn1_packer_test.cpp +++ b/tests/unittests/ngap/ngap_asn1_packer_test.cpp @@ -65,10 +65,12 @@ class ngap_asn1_packer_test : public ::testing::Test TEST_F(ngap_asn1_packer_test, when_packing_successful_then_pdu_matches_tv) { // Populate message + ngap_context_t ngap_ctxt = {{411, 22}, "srsgnb01", {{7, plmn_identity::test_value(), {{1}}}}, {}, 256}; + ngap_message ngap_msg = {}; ngap_msg.pdu.set_init_msg(); ngap_msg.pdu.init_msg().load_info_obj(ASN1_NGAP_ID_NG_SETUP); - fill_asn1_ng_setup_request(ngap_msg.pdu.init_msg().value.ng_setup_request(), generate_ng_setup_request()); + fill_asn1_ng_setup_request(ngap_msg.pdu.init_msg().value.ng_setup_request(), ngap_ctxt); // Pack message and forward to gateway packer->handle_message(ngap_msg); diff --git a/tests/unittests/ngap/ngap_test_messages.cpp b/tests/unittests/ngap/ngap_test_messages.cpp index 16e4ca235f..fdfea7eab3 100644 --- a/tests/unittests/ngap/ngap_test_messages.cpp +++ b/tests/unittests/ngap/ngap_test_messages.cpp @@ -59,34 +59,6 @@ bool srsran::srs_cu_cp::is_pdu_type(const ngap_message& return pdu.pdu.successful_outcome().value.type().value == type; } -ngap_ng_setup_request srsran::srs_cu_cp::generate_ng_setup_request() -{ - ngap_ng_setup_request request_msg; - request_msg.global_ran_node_id.gnb_id = {411, 22}; - request_msg.global_ran_node_id.plmn_id = plmn_identity::test_value(); - - request_msg.ran_node_name = "srsgnb01"; - - ngap_supported_ta_item supported_ta_item; - supported_ta_item.tac = 7; - - ngap_broadcast_plmn_item broadcast_plmn_item; - broadcast_plmn_item.plmn_id = plmn_identity::test_value(); - - slice_support_item_t slice_support_item; - slice_support_item.s_nssai.sst = 1; - - broadcast_plmn_item.tai_slice_support_list.push_back(slice_support_item); - - supported_ta_item.broadcast_plmn_list.push_back(broadcast_plmn_item); - - request_msg.supported_ta_list.push_back(supported_ta_item); - - request_msg.default_paging_drx = 256; - - return request_msg; -} - ngap_message srsran::srs_cu_cp::generate_ng_setup_response() { ngap_message ng_setup_response = {}; diff --git a/tests/unittests/ngap/ngap_test_messages.h b/tests/unittests/ngap/ngap_test_messages.h index df83af01d7..bb8d062611 100644 --- a/tests/unittests/ngap/ngap_test_messages.h +++ b/tests/unittests/ngap/ngap_test_messages.h @@ -84,9 +84,6 @@ static const uint8_t ng_setup_request_packed[] = { 0x00, 0x52, 0x40, 0x0a, 0x03, 0x80, 0x73, 0x72, 0x73, 0x67, 0x6e, 0x62, 0x30, 0x31, 0x00, 0x66, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x15, 0x40, 0x01, 0x60}; -/// \brief Generate a dummy NG Setup Request. -ngap_ng_setup_request generate_ng_setup_request(); - /// \brief Generate a dummy NG Setup Response. ngap_message generate_ng_setup_response(); From b712072b72ba366cbff7e8708022c8cfffd35928 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 30 Aug 2024 16:26:22 +0200 Subject: [PATCH 021/174] cu_up: use dedicated config for upf connection --- apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp | 6 +++--- apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp b/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp index b8a34f5d5a..3129affd32 100644 --- a/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp +++ b/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp @@ -166,9 +166,9 @@ void srsran::configure_cli11_with_cu_up_unit_config_schema(CLI::App& app, cu_up_ CLI::App* metrics_subcmd = add_subcommand(app, "metrics", "Metrics configuration")->configurable(); configure_cli11_metrics_args(*metrics_subcmd, unit_cfg.metrics); - // AMF section. - CLI::App* amf_subcmd = add_subcommand(app, "amf", "AMF parameters")->configurable(); - configure_cli11_upf_args(*amf_subcmd, unit_cfg.upf_cfg); + // UPF section. + CLI::App* upf_subcmd = add_subcommand(app, "upf", "UPF parameters")->configurable(); + configure_cli11_upf_args(*upf_subcmd, unit_cfg.upf_cfg); // QoS section. auto qos_lambda = [&unit_cfg](const std::vector& values) { diff --git a/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp b/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp index e2083f1143..64aafb5723 100644 --- a/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp +++ b/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp @@ -127,7 +127,7 @@ void srsran::fill_cu_up_config_in_yaml_schema(YAML::Node& node, const cu_up_unit fill_cu_up_log_section(node["log"], config.loggers); fill_cu_up_pcap_section(node["pcap"], config.pcap_cfg); fill_cu_up_metrics_section(node["metrics"], config.metrics); - fill_cu_up_upf_section(node["amf"], config.upf_cfg); + fill_cu_up_upf_section(node["upf"], config.upf_cfg); fill_cu_up_qos_section(node, config.qos_cfg); } From 443c9207bf78476706299f6aab0c3126843beb8a Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 30 Aug 2024 18:13:29 +0200 Subject: [PATCH 022/174] gnb,cu: autoderive upf config from cu-cp amf config --- apps/cu/cu.cpp | 4 +++- apps/gnb/gnb.cpp | 4 +++- apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp | 11 +++++++++++ apps/units/cu_up/cu_up_unit_config_cli11_schema.h | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/cu/cu.cpp b/apps/cu/cu.cpp index 0ce127c065..db5243c9b6 100644 --- a/apps/cu/cu.cpp +++ b/apps/cu/cu.cpp @@ -199,10 +199,12 @@ int main(int argc, char** argv) configure_cli11_with_cu_up_unit_config_schema(app, cu_up_config); // Set the callback for the app calling all the autoderivation functions. - app.callback([&app, &cu_cp_config]() { + app.callback([&app, &cu_cp_config, &cu_up_config]() { // Create the PLMN and TAC list from the cells. std::vector supported_tas; autoderive_cu_cp_parameters_after_parsing(app, cu_cp_config, std::move(supported_tas)); + autoderive_cu_up_parameters_after_parsing( + cu_cp_config.amf_cfg.bind_addr, cu_cp_config.amf_cfg.no_core, cu_up_config); }); // Parse arguments. diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 1edfcb212a..01cef7c497 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -229,7 +229,7 @@ int main(int argc, char** argv) configure_cli11_with_dynamic_du_unit_config_schema(app, du_unit_cfg); // Set the callback for the app calling all the autoderivation functions. - app.callback([&app, &gnb_cfg, &du_unit_cfg, &cu_cp_config]() { + app.callback([&app, &gnb_cfg, &du_unit_cfg, &cu_cp_config, &cu_up_config]() { autoderive_gnb_parameters_after_parsing(app, gnb_cfg); autoderive_slicing_args(du_unit_cfg, cu_cp_config); autoderive_dynamic_du_parameters_after_parsing(app, du_unit_cfg); @@ -253,6 +253,8 @@ int main(int argc, char** argv) } autoderive_cu_cp_parameters_after_parsing(app, cu_cp_config, std::move(supported_tas)); + autoderive_cu_up_parameters_after_parsing( + cu_cp_config.amf_cfg.bind_addr, cu_cp_config.amf_cfg.no_core, cu_up_config); }); // Parse arguments. diff --git a/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp b/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp index 3129affd32..c08c0790b3 100644 --- a/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp +++ b/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp @@ -191,3 +191,14 @@ void srsran::configure_cli11_with_cu_up_unit_config_schema(CLI::App& app, cu_up_ CLI::App* test_mode_subcmd = add_subcommand(app, "test_mode", "CU-UP test mode parameters")->configurable(); configure_cli11_test_mode_args(*test_mode_subcmd, unit_cfg.test_mode_cfg); } + +void srsran::autoderive_cu_up_parameters_after_parsing(const std::string& n2_bind_addr, + bool no_core, + cu_up_unit_config& unit_cfg) +{ + // If no UPF is configured, we autoderive the UPF configuration from the CU-CP AMF configuration. + if (unit_cfg.upf_cfg.bind_addr == "auto") { + unit_cfg.upf_cfg.bind_addr = n2_bind_addr; + } + unit_cfg.upf_cfg.no_core = no_core; +} diff --git a/apps/units/cu_up/cu_up_unit_config_cli11_schema.h b/apps/units/cu_up/cu_up_unit_config_cli11_schema.h index ff7eb3d715..2c70d5939e 100644 --- a/apps/units/cu_up/cu_up_unit_config_cli11_schema.h +++ b/apps/units/cu_up/cu_up_unit_config_cli11_schema.h @@ -19,4 +19,7 @@ struct cu_up_unit_config; /// Configures the given CLI11 application with the CU-UP application unit configuration schema. void configure_cli11_with_cu_up_unit_config_schema(CLI::App& app, cu_up_unit_config& unit_cfg); +/// Auto derive CU-UP parameters after the parsing. +void autoderive_cu_up_parameters_after_parsing(const std::string& bind_addr, bool no_core, cu_up_unit_config& unit_cfg); + } // namespace srsran From 58799176793ed7595b2a21693fe94abba962b95c Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 9 Sep 2024 12:26:06 +0200 Subject: [PATCH 023/174] cu_up: simplify upf configuration by removing redundant bind addr and n3 prefix --- apps/units/cu_up/cu_up_unit_config.h | 13 ++++++------- apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp | 13 ++++--------- apps/units/cu_up/cu_up_unit_config_translators.cpp | 10 +++------- apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp | 11 +++++------ 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/apps/units/cu_up/cu_up_unit_config.h b/apps/units/cu_up/cu_up_unit_config.h index 4f42a271a7..ff13b638c1 100644 --- a/apps/units/cu_up/cu_up_unit_config.h +++ b/apps/units/cu_up/cu_up_unit_config.h @@ -26,13 +26,12 @@ struct cu_up_unit_metrics_config { }; struct cu_up_unit_upf_config { - std::string bind_addr = "127.0.0.1"; - std::string n3_bind_addr = "auto"; - std::string n3_bind_interface = "auto"; - std::string n3_ext_addr = "auto"; - int udp_rx_max_msgs = 256; - float pool_threshold = 0.9; - bool no_core = false; + std::string bind_addr = "auto"; + std::string bind_interface = "auto"; + std::string ext_addr = "auto"; + int udp_rx_max_msgs = 256; + float pool_threshold = 0.9; + bool no_core = false; }; /// F1-U configuration at CU_UP side diff --git a/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp b/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp index c08c0790b3..44ba621151 100644 --- a/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp +++ b/apps/units/cu_up/cu_up_unit_config_cli11_schema.cpp @@ -72,18 +72,13 @@ static void configure_cli11_metrics_args(CLI::App& app, cu_up_unit_metrics_confi static void configure_cli11_upf_args(CLI::App& app, cu_up_unit_upf_config& upf_params) { - add_option(app, - "--bind_addr", - upf_params.bind_addr, - "Default local IP address interfaces bind to, unless a specific bind address is specified") - ->check(CLI::ValidIPV4); - add_option(app, "--n3_bind_addr", upf_params.n3_bind_addr, "Local IP address to bind for N3 interface") + add_option(app, "--bind_addr", upf_params.bind_addr, "Local IP address to bind for N3 interface") ->check(CLI::ValidIPV4 | CLI::IsMember({"auto"})); - add_option(app, "--n3_bind_interface", upf_params.n3_bind_interface, "Network device to bind for N3 interface") + add_option(app, "--bind_interface", upf_params.bind_interface, "Network device to bind for N3 interface") ->capture_default_str(); add_option(app, - "--n3_ext_addr", - upf_params.n3_ext_addr, + "--ext_addr", + upf_params.ext_addr, "External IP address that is advertised to receive GTP-U packets from UPF via N3 interface") ->check(CLI::ValidIPV4 | CLI::IsMember({"auto"})); add_option(app, "--udp_max_rx_msgs", upf_params.udp_rx_max_msgs, "Maximum amount of messages RX in a single syscall"); diff --git a/apps/units/cu_up/cu_up_unit_config_translators.cpp b/apps/units/cu_up/cu_up_unit_config_translators.cpp index f9c876454f..9f94399b56 100644 --- a/apps/units/cu_up/cu_up_unit_config_translators.cpp +++ b/apps/units/cu_up/cu_up_unit_config_translators.cpp @@ -22,13 +22,9 @@ srs_cu_up::cu_up_configuration srsran::generate_cu_up_config(const cu_up_unit_co out_cfg.n3_cfg.gtpu_reordering_timer = std::chrono::milliseconds{config.gtpu_reordering_timer_ms}; out_cfg.n3_cfg.warn_on_drop = config.warn_on_drop; - if (config.upf_cfg.n3_bind_addr == "auto") { - out_cfg.net_cfg.n3_bind_addr = config.upf_cfg.bind_addr; - } else { - out_cfg.net_cfg.n3_bind_addr = config.upf_cfg.n3_bind_addr; - } - out_cfg.net_cfg.n3_ext_addr = config.upf_cfg.n3_ext_addr; - out_cfg.net_cfg.n3_bind_interface = config.upf_cfg.n3_bind_interface; + out_cfg.net_cfg.n3_bind_addr = config.upf_cfg.bind_addr; + out_cfg.net_cfg.n3_ext_addr = config.upf_cfg.ext_addr; + out_cfg.net_cfg.n3_bind_interface = config.upf_cfg.bind_interface; out_cfg.net_cfg.n3_rx_max_mmsg = config.upf_cfg.udp_rx_max_msgs; out_cfg.net_cfg.pool_threshold = config.upf_cfg.pool_threshold; diff --git a/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp b/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp index 64aafb5723..c136daf752 100644 --- a/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp +++ b/apps/units/cu_up/cu_up_unit_config_yaml_writer.cpp @@ -16,12 +16,11 @@ using namespace srsran; static void fill_cu_up_upf_section(YAML::Node node, const cu_up_unit_upf_config& config) { - node["bind_addr"] = config.bind_addr; - node["n3_bind_addr"] = config.n3_bind_addr; - node["n3_bind_interface"] = config.n3_bind_interface; - node["n3_ext_addr"] = config.n3_ext_addr; - node["udp_max_rx_msgs"] = config.udp_rx_max_msgs; - node["no_core"] = config.no_core; + node["bind_addr"] = config.bind_addr; + node["bind_interface"] = config.bind_interface; + node["ext_addr"] = config.ext_addr; + node["udp_max_rx_msgs"] = config.udp_rx_max_msgs; + node["no_core"] = config.no_core; } static void fill_cu_up_metrics_section(YAML::Node node, const cu_up_unit_metrics_config& config) From 8d79d8c472f7989686268c305616e60103fdca52 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 9 Sep 2024 12:25:51 +0200 Subject: [PATCH 024/174] cu_cp: simplify amf configuration by removing redundant bind addr and n2 prefix --- apps/units/cu_cp/cu_cp_config_translators.cpp | 8 ++------ apps/units/cu_cp/cu_cp_unit_config.h | 3 +-- apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp | 9 ++------- apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp | 3 +-- 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/apps/units/cu_cp/cu_cp_config_translators.cpp b/apps/units/cu_cp/cu_cp_config_translators.cpp index 4a1f8835cb..d2ae9a5963 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.cpp +++ b/apps/units/cu_cp/cu_cp_config_translators.cpp @@ -439,12 +439,8 @@ srsran::generate_n2_client_config(const cu_cp_unit_amf_config& amf_cfg, dlt_pcap network_mode_t& nw_mode = std::get(mode); nw_mode.amf_address = amf_cfg.ip_addr; nw_mode.amf_port = amf_cfg.port; - if (amf_cfg.n2_bind_addr == "auto") { - nw_mode.bind_address = amf_cfg.bind_addr; - } else { - nw_mode.bind_address = amf_cfg.n2_bind_addr; - } - nw_mode.bind_interface = amf_cfg.n2_bind_interface; + nw_mode.bind_address = amf_cfg.bind_addr; + nw_mode.bind_interface = amf_cfg.bind_interface; if (amf_cfg.sctp_rto_initial >= 0) { nw_mode.rto_initial = amf_cfg.sctp_rto_initial; } diff --git a/apps/units/cu_cp/cu_cp_unit_config.h b/apps/units/cu_cp/cu_cp_unit_config.h index 50e0d955f0..beaba9e031 100644 --- a/apps/units/cu_cp/cu_cp_unit_config.h +++ b/apps/units/cu_cp/cu_cp_unit_config.h @@ -227,8 +227,7 @@ struct cu_cp_unit_amf_config { std::string ip_addr = "127.0.0.1"; uint16_t port = 38412; std::string bind_addr = "127.0.0.1"; - std::string n2_bind_addr = "auto"; - std::string n2_bind_interface = "auto"; + std::string bind_interface = "auto"; int sctp_rto_initial = 120; int sctp_rto_min = 120; int sctp_rto_max = 500; diff --git a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp index 13c2d8ecfe..52b57eeda6 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp +++ b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp @@ -455,14 +455,9 @@ static void configure_cli11_amf_args(CLI::App& app, cu_cp_unit_amf_config& amf_p { add_option(app, "--addr", amf_params.ip_addr, "AMF IP address"); add_option(app, "--port", amf_params.port, "AMF port")->capture_default_str()->check(CLI::Range(20000, 40000)); - add_option(app, - "--bind_addr", - amf_params.bind_addr, - "Default local IP address interfaces bind to, unless a specific bind address is specified") + add_option(app, "--bind_addr", amf_params.bind_addr, "Local IP address to bind for N2 interface") ->check(CLI::ValidIPV4); - add_option(app, "--n2_bind_addr", amf_params.n2_bind_addr, "Local IP address to bind for N2 interface") - ->check(CLI::ValidIPV4 | CLI::IsMember({"auto"})); - add_option(app, "--n2_bind_interface", amf_params.n2_bind_interface, "Network device to bind for N2 interface") + add_option(app, "--bind_interface", amf_params.bind_interface, "Network device to bind for N2 interface") ->capture_default_str(); add_option(app, "--sctp_rto_initial", amf_params.sctp_rto_initial, "SCTP initial RTO value"); add_option(app, "--sctp_rto_min", amf_params.sctp_rto_min, "SCTP RTO min"); diff --git a/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp b/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp index 8246010f87..9615048619 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp +++ b/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp @@ -19,8 +19,7 @@ static void fill_cu_cp_amf_section(YAML::Node node, const cu_cp_unit_amf_config& node["addr"] = config.ip_addr; node["port"] = config.port; node["bind_addr"] = config.bind_addr; - node["n2_bind_addr"] = config.n2_bind_addr; - node["n2_bind_interface"] = config.n2_bind_interface; + node["bind_interface"] = config.bind_interface; node["sctp_rto_initial"] = config.sctp_rto_initial; node["sctp_rto_min"] = config.sctp_rto_min; node["sctp_rto_max"] = config.sctp_rto_max; From ddebfe6bb8b149f4dd30f0e29c2f32dbb376ea04 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 30 Aug 2024 16:04:34 +0200 Subject: [PATCH 025/174] cu_cp,ngap: add ngap repository --- include/srsran/cu_cp/cu_cp_configuration.h | 9 +++ include/srsran/ngap/ngap.h | 4 + include/srsran/ran/plmn_identity.h | 9 +++ lib/cu_cp/CMakeLists.txt | 1 + lib/cu_cp/adapters/ngap_adapters.h | 2 - lib/cu_cp/ngap_repository.cpp | 94 ++++++++++++++++++++++ lib/cu_cp/ngap_repository.h | 78 ++++++++++++++++++ lib/ngap/ngap_impl.cpp | 11 +++ lib/ngap/ngap_impl.h | 9 ++- 9 files changed, 211 insertions(+), 6 deletions(-) create mode 100644 lib/cu_cp/ngap_repository.cpp create mode 100644 lib/cu_cp/ngap_repository.h diff --git a/include/srsran/cu_cp/cu_cp_configuration.h b/include/srsran/cu_cp/cu_cp_configuration.h index 390d010fe7..771f7122cd 100644 --- a/include/srsran/cu_cp/cu_cp_configuration.h +++ b/include/srsran/cu_cp/cu_cp_configuration.h @@ -59,6 +59,13 @@ struct cu_cp_configuration { n2_connection_client* n2_gw = nullptr; timer_manager* timers = nullptr; }; + + struct ngap_params { + n2_connection_client* n2_gw = nullptr; + // Supported TAs for each AMF. + std::vector supported_tas; + }; + struct rrc_params { /// Force re-establishment fallback. bool force_reestablishment_fallback = false; @@ -90,6 +97,8 @@ struct cu_cp_configuration { ran_node_configuration node; /// Parameters to determine the admission of new CU-UP, DU and UE connections. admission_params admission; + /// NGAP layer-specific parameters. + std::vector ngaps; /// RRC layer-specific parameters. rrc_params rrc; /// F1AP layer-specific parameters. diff --git a/include/srsran/ngap/ngap.h b/include/srsran/ngap/ngap.h index 0db0afd693..55a78757a4 100644 --- a/include/srsran/ngap/ngap.h +++ b/include/srsran/ngap/ngap.h @@ -16,6 +16,7 @@ #include "srsran/ngap/ngap_reset.h" #include "srsran/ngap/ngap_setup.h" #include "srsran/ngap/ngap_ue_radio_capability_management.h" +#include "srsran/ran/plmn_identity.h" #include "srsran/support/async/async_task.h" namespace srsran { @@ -247,6 +248,9 @@ class ngap_control_message_handler virtual void handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t ue_index, const nr_cell_global_id_t& cgi, const unsigned tac) = 0; + + /// \brief Get the supported PLMNs. + virtual std::vector get_supported_plmns() const = 0; }; /// Interface to control the NGAP. diff --git a/include/srsran/ran/plmn_identity.h b/include/srsran/ran/plmn_identity.h index 82ec3502ab..016f9e8298 100644 --- a/include/srsran/ran/plmn_identity.h +++ b/include/srsran/ran/plmn_identity.h @@ -220,6 +220,15 @@ class plmn_identity } // namespace srsran +namespace std { + +template <> +struct hash { + size_t operator()(const srsran::plmn_identity& s) const noexcept { return hash{}(s.to_string()); } +}; + +} // namespace std + namespace fmt { template <> diff --git a/lib/cu_cp/CMakeLists.txt b/lib/cu_cp/CMakeLists.txt index 095d04470c..d6e1bb22bd 100644 --- a/lib/cu_cp/CMakeLists.txt +++ b/lib/cu_cp/CMakeLists.txt @@ -26,6 +26,7 @@ set(SOURCES du_processor/du_processor_factory.cpp du_processor/du_processor_repository.cpp metrics_handler/metrics_handler_impl.cpp + ngap_repository.cpp routines/amf_connection_setup_routine.cpp routines/initial_context_setup_routine.cpp routines/pdu_session_routine_helpers.cpp diff --git a/lib/cu_cp/adapters/ngap_adapters.h b/lib/cu_cp/adapters/ngap_adapters.h index 9c70a7dfad..65acbed137 100644 --- a/lib/cu_cp/adapters/ngap_adapters.h +++ b/lib/cu_cp/adapters/ngap_adapters.h @@ -25,8 +25,6 @@ namespace srs_cu_cp { class ngap_cu_cp_adapter : public ngap_cu_cp_notifier { public: - explicit ngap_cu_cp_adapter() = default; - void connect_cu_cp(cu_cp_ngap_handler& cu_cp_handler_, paging_message_handler& paging_handler_) { cu_cp_handler = &cu_cp_handler_; diff --git a/lib/cu_cp/ngap_repository.cpp b/lib/cu_cp/ngap_repository.cpp new file mode 100644 index 0000000000..9c7effeedc --- /dev/null +++ b/lib/cu_cp/ngap_repository.cpp @@ -0,0 +1,94 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "ngap_repository.h" +#include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/ngap/ngap_factory.h" +#include "srsran/support/srsran_assert.h" + +using namespace srsran; +using namespace srs_cu_cp; + +ngap_repository::ngap_repository(ngap_repository_config cfg_) : cfg(cfg_), logger(cfg.logger) +{ + for (uint16_t amf_idx = 0; amf_idx < cfg.cu_cp.ngaps.size(); amf_idx++) { + auto* ngap_entity = add_ngap(uint_to_amf_index(amf_idx), cfg.cu_cp.ngaps.at(amf_idx)); + srsran_assert(ngap_entity != nullptr, "Failed to add NGAP for gateway"); + } +} + +ngap_interface* ngap_repository::add_ngap(amf_index_t amf_index, const cu_cp_configuration::ngap_params& config) +{ + // Create NGAP object + auto it = ngap_db.insert(std::make_pair(amf_index, ngap_context{})); + srsran_assert(it.second, "Unable to insert NGAP in map"); + ngap_context& ngap_ctxt = it.first->second; + ngap_ctxt.ngap_to_cu_cp_notifier.connect_cu_cp(cfg.cu_cp_notifier, cfg.paging_handler); + + ngap_configuration ngap_cfg = {cfg.cu_cp.node.gnb_id, + cfg.cu_cp.node.ran_node_name, + config.supported_tas, + cfg.cu_cp.ue.pdu_session_setup_timeout}; + std::unique_ptr ngap_entity = create_ngap(ngap_cfg, + ngap_ctxt.ngap_to_cu_cp_notifier, + *config.n2_gw, + *cfg.cu_cp.services.timers, + *cfg.cu_cp.services.cu_cp_executor); + + if (ngap_entity == nullptr) { + logger.error("Failed to create NGAP"); + return nullptr; + } + + ngap_ctxt.ngap = std::move(ngap_entity); + + return ngap_ctxt.ngap.get(); +} + +void ngap_repository::update_plmn_lookup(amf_index_t amf_index) +{ + auto ngap = ngap_db.find(amf_index); + if (ngap == ngap_db.end()) { + logger.error("NGAP not found for AMF index {}", amf_index); + return; + } + + std::vector supported_plmns = ngap->second.ngap->get_supported_plmns(); + for (auto plmn : supported_plmns) { + plmn_to_amf_index.emplace(plmn, amf_index); + } +} + +ngap_interface* ngap_repository::find_ngap(const plmn_identity& plmn) +{ + if (plmn_to_amf_index.find(plmn) == plmn_to_amf_index.end()) { + return nullptr; + } + + return ngap_db.at(plmn_to_amf_index.at(plmn)).ngap.get(); +} + +std::map ngap_repository::get_ngaps() +{ + std::map ngaps; + for (auto& amf : ngap_db) { + ngaps.emplace(amf.first, amf.second.ngap.get()); + } + return ngaps; +} + +size_t ngap_repository::get_nof_ngap_ues() +{ + size_t nof_ues = 0; + for (auto& du : ngap_db) { + nof_ues += du.second.ngap->get_nof_ues(); + } + return nof_ues; +} diff --git a/lib/cu_cp/ngap_repository.h b/lib/cu_cp/ngap_repository.h new file mode 100644 index 0000000000..8e208e950c --- /dev/null +++ b/lib/cu_cp/ngap_repository.h @@ -0,0 +1,78 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "adapters/ngap_adapters.h" +#include "srsran/cu_cp/cu_cp_configuration.h" +#include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/ngap/gateways/n2_connection_client.h" +#include "srsran/ngap/ngap.h" +#include "srsran/ran/plmn_identity.h" + +namespace srsran { +namespace srs_cu_cp { + +struct cu_cp_configuration; + +struct ngap_repository_config { + const cu_cp_configuration& cu_cp; + cu_cp_ngap_handler& cu_cp_notifier; + paging_message_handler& paging_handler; + srslog::basic_logger& logger; +}; + +class ngap_repository +{ +public: + explicit ngap_repository(ngap_repository_config cfg_); + + /// \brief Adds a NGAP object to the CU-CP. + /// \return A pointer to the interface of the added NGAP object if it was successfully created, a nullptr otherwise. + ngap_interface* add_ngap(amf_index_t amf_index, const cu_cp_configuration::ngap_params& config); + + /// \brief Updates the PLMN lookup table with the PLMNs supported by the connected NGAP. + /// \param[in] amf_index The AMF index to identify the NGAP. + void update_plmn_lookup(amf_index_t amf_index); + + /// \brief Checks whether a AMF with the specified PLMN is served by any of the connected NGAPs. + /// \param[in] plmn The PLMN to identify the NGAP. + /// \return The interface of the NGAP for the given PLMN if it is found, nullptr if no NGAP for the PLMN is found. + ngap_interface* find_ngap(const plmn_identity& plmn); + + /// \brief Get the all NGAP interfaces. + std::map get_ngaps(); + + /// Number of NGAPs managed by the CU-CP. + size_t get_nof_ngaps() const { return ngap_db.size(); } + + /// Number of UEs managed by the CU-CP. + size_t get_nof_ngap_ues(); + +private: + struct ngap_context { + // CU-CP handler of NGAP events. + ngap_cu_cp_adapter ngap_to_cu_cp_notifier; + + std::unique_ptr ngap; + + /// Notifier used by the CU-CP to push NGAP Tx messages to the respective AMF. + std::unique_ptr ngap_tx_pdu_notifier; + }; + + ngap_repository_config cfg; + srslog::basic_logger& logger; + + std::unordered_map plmn_to_amf_index; + std::map ngap_db; +}; + +} // namespace srs_cu_cp +} // namespace srsran diff --git a/lib/ngap/ngap_impl.cpp b/lib/ngap/ngap_impl.cpp index cab14b8c40..86760541a3 100644 --- a/lib/ngap/ngap_impl.cpp +++ b/lib/ngap/ngap_impl.cpp @@ -975,6 +975,17 @@ void ngap_impl::handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t tx_pdu_notifier->on_new_message(ngap_msg); } +std::vector ngap_impl::get_supported_plmns() const +{ + std::vector supported_plmns; + supported_plmns.reserve(context.served_guami_list.size()); + for (const auto& guami : context.served_guami_list) { + supported_plmns.push_back(guami.plmn); + } + + return supported_plmns; +} + void ngap_impl::remove_ue_context(ue_index_t ue_index) { if (!ue_ctxt_list.contains(ue_index)) { diff --git a/lib/ngap/ngap_impl.h b/lib/ngap/ngap_impl.h index 7d523ec9b4..c3867c2e71 100644 --- a/lib/ngap/ngap_impl.h +++ b/lib/ngap/ngap_impl.h @@ -61,10 +61,11 @@ class ngap_impl final : public ngap_interface // ngap_control_message_handler async_task handle_ue_context_release_request(const cu_cp_ue_context_release_request& msg) override; async_task - handle_handover_preparation_request(const ngap_handover_preparation_request& msg) override; - void handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t ue_index, - const nr_cell_global_id_t& cgi, - const unsigned tac) override; + handle_handover_preparation_request(const ngap_handover_preparation_request& msg) override; + void handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t ue_index, + const nr_cell_global_id_t& cgi, + const unsigned tac) override; + std::vector get_supported_plmns() const override; // ngap_statistics_handler size_t get_nof_ues() const override { return ue_ctxt_list.size(); } From d53817379a12a817ffd3056964b109618faed410 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 3 Sep 2024 17:18:42 +0200 Subject: [PATCH 026/174] cu_cp,ngap: replace single field getter by context getter --- include/srsran/ngap/ngap.h | 4 ++-- {lib => include/srsran}/ngap/ngap_context.h | 11 +++++++++++ lib/cu_cp/ngap_repository.cpp | 3 ++- lib/ngap/ngap_asn1_helpers.h | 3 +-- lib/ngap/ngap_impl.cpp | 11 ----------- lib/ngap/ngap_impl.h | 11 +++++------ lib/ngap/procedures/ng_setup_procedure.h | 2 +- .../procedures/ngap_handover_preparation_procedure.h | 1 - 8 files changed, 22 insertions(+), 24 deletions(-) rename {lib => include/srsran}/ngap/ngap_context.h (77%) diff --git a/include/srsran/ngap/ngap.h b/include/srsran/ngap/ngap.h index 55a78757a4..984ece4864 100644 --- a/include/srsran/ngap/ngap.h +++ b/include/srsran/ngap/ngap.h @@ -11,12 +11,12 @@ #pragma once #include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/ngap/ngap_context.h" #include "srsran/ngap/ngap_handover.h" #include "srsran/ngap/ngap_init_context_setup.h" #include "srsran/ngap/ngap_reset.h" #include "srsran/ngap/ngap_setup.h" #include "srsran/ngap/ngap_ue_radio_capability_management.h" -#include "srsran/ran/plmn_identity.h" #include "srsran/support/async/async_task.h" namespace srsran { @@ -250,7 +250,7 @@ class ngap_control_message_handler const unsigned tac) = 0; /// \brief Get the supported PLMNs. - virtual std::vector get_supported_plmns() const = 0; + virtual const ngap_context_t& get_ngap_context() const = 0; }; /// Interface to control the NGAP. diff --git a/lib/ngap/ngap_context.h b/include/srsran/ngap/ngap_context.h similarity index 77% rename from lib/ngap/ngap_context.h rename to include/srsran/ngap/ngap_context.h index 3761c68b32..8fef75d969 100644 --- a/lib/ngap/ngap_context.h +++ b/include/srsran/ngap/ngap_context.h @@ -29,6 +29,17 @@ struct ngap_context_t { std::vector served_guami_list; uint16_t default_paging_drx = 256; // default paging drx std::chrono::seconds pdu_session_setup_timeout; // timeout for PDU context setup in seconds + + std::vector get_supported_plmns() const + { + std::vector supported_plmns; + supported_plmns.reserve(supported_tas.size()); + for (const auto& ta : supported_tas) { + supported_plmns.push_back(ta.plmn); + } + + return supported_plmns; + } }; } // namespace srs_cu_cp diff --git a/lib/cu_cp/ngap_repository.cpp b/lib/cu_cp/ngap_repository.cpp index 9c7effeedc..70c9320a4f 100644 --- a/lib/cu_cp/ngap_repository.cpp +++ b/lib/cu_cp/ngap_repository.cpp @@ -10,6 +10,7 @@ #include "ngap_repository.h" #include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/ngap/ngap_context.h" #include "srsran/ngap/ngap_factory.h" #include "srsran/support/srsran_assert.h" @@ -60,7 +61,7 @@ void ngap_repository::update_plmn_lookup(amf_index_t amf_index) return; } - std::vector supported_plmns = ngap->second.ngap->get_supported_plmns(); + std::vector supported_plmns = ngap->second.ngap->get_ngap_context().get_supported_plmns(); for (auto plmn : supported_plmns) { plmn_to_amf_index.emplace(plmn, amf_index); } diff --git a/lib/ngap/ngap_asn1_helpers.h b/lib/ngap/ngap_asn1_helpers.h index ad206c582b..f7d4907ed0 100644 --- a/lib/ngap/ngap_asn1_helpers.h +++ b/lib/ngap/ngap_asn1_helpers.h @@ -11,13 +11,12 @@ #pragma once #include "ngap_asn1_converters.h" -#include "ngap_context.h" #include "srsran/adt/byte_buffer.h" -#include "srsran/adt/optional.h" #include "srsran/asn1/asn1_utils.h" #include "srsran/asn1/ngap/ngap_ies.h" #include "srsran/asn1/ngap/ngap_pdu_contents.h" #include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/ngap/ngap_context.h" #include "srsran/ngap/ngap_handover.h" #include "srsran/ngap/ngap_init_context_setup.h" #include "srsran/ngap/ngap_nas.h" diff --git a/lib/ngap/ngap_impl.cpp b/lib/ngap/ngap_impl.cpp index 86760541a3..cab14b8c40 100644 --- a/lib/ngap/ngap_impl.cpp +++ b/lib/ngap/ngap_impl.cpp @@ -975,17 +975,6 @@ void ngap_impl::handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t tx_pdu_notifier->on_new_message(ngap_msg); } -std::vector ngap_impl::get_supported_plmns() const -{ - std::vector supported_plmns; - supported_plmns.reserve(context.served_guami_list.size()); - for (const auto& guami : context.served_guami_list) { - supported_plmns.push_back(guami.plmn); - } - - return supported_plmns; -} - void ngap_impl::remove_ue_context(ue_index_t ue_index) { if (!ue_ctxt_list.contains(ue_index)) { diff --git a/lib/ngap/ngap_impl.h b/lib/ngap/ngap_impl.h index c3867c2e71..7182708907 100644 --- a/lib/ngap/ngap_impl.h +++ b/lib/ngap/ngap_impl.h @@ -11,7 +11,6 @@ #pragma once #include "ngap_connection_handler.h" -#include "ngap_context.h" #include "ngap_error_indication_helper.h" #include "procedures/ngap_transaction_manager.h" #include "ue_context/ngap_ue_context.h" @@ -61,11 +60,11 @@ class ngap_impl final : public ngap_interface // ngap_control_message_handler async_task handle_ue_context_release_request(const cu_cp_ue_context_release_request& msg) override; async_task - handle_handover_preparation_request(const ngap_handover_preparation_request& msg) override; - void handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t ue_index, - const nr_cell_global_id_t& cgi, - const unsigned tac) override; - std::vector get_supported_plmns() const override; + handle_handover_preparation_request(const ngap_handover_preparation_request& msg) override; + void handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t ue_index, + const nr_cell_global_id_t& cgi, + const unsigned tac) override; + const ngap_context_t& get_ngap_context() const override { return context; }; // ngap_statistics_handler size_t get_nof_ues() const override { return ue_ctxt_list.size(); } diff --git a/lib/ngap/procedures/ng_setup_procedure.h b/lib/ngap/procedures/ng_setup_procedure.h index 71677ed61b..5a771ab98b 100644 --- a/lib/ngap/procedures/ng_setup_procedure.h +++ b/lib/ngap/procedures/ng_setup_procedure.h @@ -10,9 +10,9 @@ #pragma once -#include "../ngap_context.h" #include "ngap_transaction_manager.h" #include "srsran/ngap/ngap.h" +#include "srsran/ngap/ngap_context.h" #include "srsran/ngap/ngap_message.h" #include "srsran/support/async/async_task.h" diff --git a/lib/ngap/procedures/ngap_handover_preparation_procedure.h b/lib/ngap/procedures/ngap_handover_preparation_procedure.h index f4d94f4e67..e48aa7d829 100644 --- a/lib/ngap/procedures/ngap_handover_preparation_procedure.h +++ b/lib/ngap/procedures/ngap_handover_preparation_procedure.h @@ -10,7 +10,6 @@ #pragma once -#include "../ngap_context.h" #include "../ue_context/ngap_ue_context.h" #include "ngap_transaction_manager.h" #include "srsran/asn1/ngap/ngap_pdu_contents.h" From a6e7ac463892fad1e22b7755c04557266c5395cd Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 11 Sep 2024 16:27:47 +0200 Subject: [PATCH 027/174] cu_cp: simplify unit test setup --- tests/unittests/cu_cp/cu_cp_connectivity_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_inactivity_notification_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_paging_test.cpp | 2 +- .../unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp | 3 +-- .../cu_cp/cu_cp_pdu_session_resource_release_test.cpp | 3 +-- .../unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_setup_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp | 2 +- 12 files changed, 12 insertions(+), 14 deletions(-) diff --git a/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp b/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp index 630b1f544b..aed483e637 100644 --- a/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp @@ -29,7 +29,7 @@ using namespace srs_cu_cp; class cu_cp_connectivity_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_connectivity_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) {} + cu_cp_connectivity_test() : cu_cp_test_environment(cu_cp_test_env_params{}) {} }; //----------------------------------------------------------------------------------// diff --git a/tests/unittests/cu_cp/cu_cp_inactivity_notification_test.cpp b/tests/unittests/cu_cp/cu_cp_inactivity_notification_test.cpp index 1deabb3511..550ed27335 100644 --- a/tests/unittests/cu_cp/cu_cp_inactivity_notification_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_inactivity_notification_test.cpp @@ -22,7 +22,7 @@ using namespace srs_cu_cp; class cu_cp_inactivity_notification_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_inactivity_notification_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_inactivity_notification_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp index 383aa6ad3a..60c1e7e405 100644 --- a/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp @@ -29,7 +29,7 @@ using namespace srs_cu_cp; class cu_cp_initial_context_setup_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_initial_context_setup_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_initial_context_setup_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp b/tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp index 21e5c64ca6..af434fa477 100644 --- a/tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp @@ -31,7 +31,7 @@ using namespace srs_cu_cp; class cu_cp_inter_cu_handover_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_inter_cu_handover_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_inter_cu_handover_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp b/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp index 8a00272d2e..c02184c468 100644 --- a/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp @@ -27,7 +27,7 @@ using namespace srs_cu_cp; class cu_cp_inter_du_handover_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_inter_du_handover_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_inter_du_handover_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_paging_test.cpp b/tests/unittests/cu_cp/cu_cp_paging_test.cpp index a71b3f0dc9..06cda40590 100644 --- a/tests/unittests/cu_cp/cu_cp_paging_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_paging_test.cpp @@ -25,7 +25,7 @@ using namespace srs_cu_cp; class cu_cp_paging_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_paging_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_paging_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp index 252dab02a3..cd5fb0bb3c 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp @@ -34,8 +34,7 @@ using namespace srs_cu_cp; class cu_cp_pdu_session_resource_modify_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_pdu_session_resource_modify_test() : - cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_pdu_session_resource_modify_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp index 10a023c1a8..ead31e5bef 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp @@ -31,8 +31,7 @@ using namespace srs_cu_cp; class cu_cp_pdu_session_resource_release_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_pdu_session_resource_release_test() : - cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_pdu_session_resource_release_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp index c725bc70ca..7505a217ad 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp @@ -31,7 +31,7 @@ using namespace srs_cu_cp; class cu_cp_pdu_session_resource_setup_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_pdu_session_resource_setup_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_pdu_session_resource_setup_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp b/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp index 711da5734f..d2cf3cbf96 100644 --- a/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp @@ -27,7 +27,7 @@ using namespace srs_cu_cp; class cu_cp_reestablishment_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_reestablishment_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_reestablishment_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_setup_test.cpp index f476d2bcf5..be0fc0b74a 100644 --- a/tests/unittests/cu_cp/cu_cp_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_setup_test.cpp @@ -26,7 +26,7 @@ using namespace srs_cu_cp; class cu_cp_setup_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_setup_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_setup_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); diff --git a/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp b/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp index 25c1fcb4e7..02123d5682 100644 --- a/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp @@ -29,7 +29,7 @@ using namespace srs_cu_cp; class cu_cp_ue_context_release_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_ue_context_release_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()}) + cu_cp_ue_context_release_test() : cu_cp_test_environment(cu_cp_test_env_params{}) { // Run NG setup to completion. run_ng_setup(); From a43ff77197b27a23c62b8b63a55e78cf8ec4469e Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Thu, 12 Sep 2024 17:10:55 +0200 Subject: [PATCH 028/174] gnb,cu,cu_cp: add support for multiple plmns per ta and move amf config to cu-cp config --- apps/cu/cu.cpp | 22 +-- apps/gnb/gnb.cpp | 45 +++--- apps/gnb/gnb_appconfig_validators.cpp | 20 ++- apps/units/cu_cp/cu_cp_builder.cpp | 5 +- apps/units/cu_cp/cu_cp_builder.h | 8 +- apps/units/cu_cp/cu_cp_config_translators.cpp | 42 +++-- apps/units/cu_cp/cu_cp_config_translators.h | 8 +- apps/units/cu_cp/cu_cp_unit_config.h | 51 +++--- .../cu_cp/cu_cp_unit_config_cli11_schema.cpp | 153 +++++++++++------- .../cu_cp/cu_cp_unit_config_cli11_schema.h | 6 +- .../cu_cp/cu_cp_unit_config_validator.cpp | 76 +++++---- .../cu_cp/cu_cp_unit_config_yaml_writer.cpp | 77 ++++++--- configs/amf.yml | 13 ++ configs/tracking_areas.yml | 13 -- include/srsran/cu_cp/cu_cp_configuration.h | 21 +-- .../cu_cp/cu_cp_configuration_helpers.h | 15 +- include/srsran/cu_cp/cu_cp_ng_handler.h | 16 +- include/srsran/cu_cp/cu_cp_types.h | 2 + .../srsran/ngap/ngap_configuration_helpers.h | 11 -- include/srsran/ngap/ngap_context.h | 5 +- include/srsran/rrc/rrc_ue.h | 3 +- lib/cu_cp/CMakeLists.txt | 1 + lib/cu_cp/adapters/rrc_ue_adapters.h | 32 ++-- .../amf_connection_manager.cpp | 127 +++++++++++---- .../cu_cp_controller/amf_connection_manager.h | 29 +++- .../cu_cp_controller/cu_cp_controller.cpp | 56 ++----- lib/cu_cp/cu_cp_controller/cu_cp_controller.h | 15 +- .../cu_cp_ue_admission_controller.h | 6 +- lib/cu_cp/cu_cp_impl.cpp | 128 +++++++++------ lib/cu_cp/cu_cp_impl.h | 18 ++- .../du_processor/du_processor_repository.cpp | 4 +- .../mobility_manager_factory.cpp | 4 +- .../mobility_manager_factory.h | 2 +- .../mobility_manager_impl.cpp | 24 ++- .../mobility_manager/mobility_manager_impl.h | 5 +- .../amf_connection_removal_routine.cpp | 40 +++++ .../routines/amf_connection_removal_routine.h | 35 ++++ .../routines/amf_connection_setup_routine.cpp | 43 ++++- .../routines/amf_connection_setup_routine.h | 12 +- lib/ngap/ngap_asn1_helpers.h | 25 +-- lib/rrc/ue/procedures/rrc_setup_procedure.cpp | 1 + lib/rrc/ue/rrc_ue_message_handlers.cpp | 3 +- .../du_high_cu/cu_du_test.cpp | 3 +- .../du_high_cu/du_high_cu_test_simulator.cpp | 7 +- .../ngap/ngap_integration_test.cpp | 26 +-- .../cu_cp/cu_cp_connectivity_test.cpp | 6 +- .../cu_cp/cu_cp_test_environment.cpp | 29 ++-- .../unittests/cu_cp/cu_cp_test_environment.h | 41 +++-- .../du_processor_test_helpers.cpp | 7 +- .../f1ap/common/f1ap_cu_test_messages.h | 2 +- .../unittests/ngap/ngap_asn1_packer_test.cpp | 2 +- tests/unittests/ngap/ngap_test_helpers.cpp | 6 +- tests/unittests/ngap/ngap_test_messages.cpp | 7 +- tests/unittests/ngap/ngap_test_messages.h | 2 +- tests/unittests/rrc/test_helpers.h | 2 +- 55 files changed, 870 insertions(+), 492 deletions(-) create mode 100644 configs/amf.yml delete mode 100644 configs/tracking_areas.yml create mode 100644 lib/cu_cp/routines/amf_connection_removal_routine.cpp create mode 100644 lib/cu_cp/routines/amf_connection_removal_routine.h diff --git a/apps/cu/cu.cpp b/apps/cu/cu.cpp index db5243c9b6..6a611795bf 100644 --- a/apps/cu/cu.cpp +++ b/apps/cu/cu.cpp @@ -200,11 +200,9 @@ int main(int argc, char** argv) // Set the callback for the app calling all the autoderivation functions. app.callback([&app, &cu_cp_config, &cu_up_config]() { - // Create the PLMN and TAC list from the cells. - std::vector supported_tas; - autoderive_cu_cp_parameters_after_parsing(app, cu_cp_config, std::move(supported_tas)); + autoderive_cu_cp_parameters_after_parsing(app, cu_cp_config); autoderive_cu_up_parameters_after_parsing( - cu_cp_config.amf_cfg.bind_addr, cu_cp_config.amf_cfg.no_core, cu_up_config); + cu_cp_config.amf_config.amf.bind_addr, cu_cp_config.amf_config.no_core, cu_up_config); }); // Parse arguments. @@ -312,17 +310,21 @@ int main(int argc, char** argv) // Create time source that ticks the timers io_timer_source time_source{app_timers, *epoll_broker, std::chrono::milliseconds{1}}; - // Create N2 Client Gateway. - std::unique_ptr n2_client = srs_cu_cp::create_n2_connection_client( - generate_n2_client_config(cu_cp_config.amf_cfg, *cu_cp_dlt_pcaps.ngap, *epoll_broker)); - // Create CU-CP config. cu_cp_build_dependencies cu_cp_dependencies; cu_cp_dependencies.cu_cp_executor = workers.cu_cp_exec; cu_cp_dependencies.cu_cp_e2_exec = workers.cu_cp_e2_exec; - cu_cp_dependencies.n2_client = n2_client.get(); cu_cp_dependencies.timers = cu_timers; + // Create N2 Client Gateways. + cu_cp_dependencies.n2_clients.push_back(srs_cu_cp::create_n2_connection_client(generate_n2_client_config( + cu_cp_config.amf_config.no_core, cu_cp_config.amf_config.amf, *cu_cp_dlt_pcaps.ngap, *epoll_broker))); + + for (const auto& amf : cu_cp_config.extra_amfs) { + cu_cp_dependencies.n2_clients.push_back(srs_cu_cp::create_n2_connection_client( + generate_n2_client_config(cu_cp_config.amf_config.no_core, amf, *cu_cp_dlt_pcaps.ngap, *epoll_broker))); + } + // create CU-CP. auto cu_cp_obj_and_cmds = build_cu_cp(cu_cp_config, cu_cp_dependencies); srs_cu_cp::cu_cp& cu_cp_obj = *cu_cp_obj_and_cmds.unit; @@ -339,7 +341,7 @@ int main(int argc, char** argv) cu_logger.info("CU-CP started successfully"); // Check connection to AMF - if (not cu_cp_obj.get_ng_handler().amf_is_connected()) { + if (not cu_cp_obj.get_ng_handler().amfs_are_connected()) { report_error("CU-CP failed to connect to AMF"); } diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 01cef7c497..9521f58ac9 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -234,27 +234,14 @@ int main(int argc, char** argv) autoderive_slicing_args(du_unit_cfg, cu_cp_config); autoderive_dynamic_du_parameters_after_parsing(app, du_unit_cfg); - // Create the supported tracking areas list from the cells. - // These will only be used if no supported TAs are provided in the CU-CP configuration. - std::vector supported_tas; - supported_tas.reserve(du_unit_cfg.du_high_cfg.config.cells_cfg.size()); - for (const auto& cell : du_unit_cfg.du_high_cfg.config.cells_cfg) { - // Make sure supported tracking areas are unique. - if (std::find_if(supported_tas.begin(), supported_tas.end(), [&cell](const auto& ta) { - return ta.tac == cell.cell.tac && ta.plmn == cell.cell.plmn; - }) == supported_tas.end()) { - supported_tas.push_back({cell.cell.tac, cell.cell.plmn, {{1}}}); - } - } - // If test mode is enabled, we auto-enable "no_core" option if (du_unit_cfg.du_high_cfg.config.test_mode_cfg.test_ue.rnti != rnti_t::INVALID_RNTI) { - cu_cp_config.amf_cfg.no_core = true; + cu_cp_config.amf_config.no_core = true; } - autoderive_cu_cp_parameters_after_parsing(app, cu_cp_config, std::move(supported_tas)); + autoderive_cu_cp_parameters_after_parsing(app, cu_cp_config); autoderive_cu_up_parameters_after_parsing( - cu_cp_config.amf_cfg.bind_addr, cu_cp_config.amf_cfg.no_core, cu_up_config); + cu_cp_config.amf_config.amf.bind_addr, cu_cp_config.amf_config.no_core, cu_up_config); }); // Parse arguments. @@ -380,9 +367,20 @@ int main(int argc, char** argv) e2_metric_connector_manager e2_metric_connectors(du_unit_cfg.du_high_cfg.config.cells_cfg.size()); - // Create N2 Gateway. - std::unique_ptr n2_client = srs_cu_cp::create_n2_connection_client( - generate_n2_client_config(cu_cp_config.amf_cfg, *cu_cp_dlt_pcaps.ngap, *epoll_broker)); + // Create CU-CP config. + cu_cp_build_dependencies cu_cp_dependencies; + cu_cp_dependencies.cu_cp_executor = workers.cu_cp_exec; + cu_cp_dependencies.cu_cp_e2_exec = workers.cu_cp_e2_exec; + cu_cp_dependencies.timers = cu_timers; + + // Create N2 Client Gateways. + cu_cp_dependencies.n2_clients.push_back(srs_cu_cp::create_n2_connection_client(generate_n2_client_config( + cu_cp_config.amf_config.no_core, cu_cp_config.amf_config.amf, *cu_cp_dlt_pcaps.ngap, *epoll_broker))); + + for (const auto& amf : cu_cp_config.extra_amfs) { + cu_cp_dependencies.n2_clients.push_back(srs_cu_cp::create_n2_connection_client( + generate_n2_client_config(cu_cp_config.amf_config.no_core, amf, *cu_cp_dlt_pcaps.ngap, *epoll_broker))); + } // E2AP configuration. srsran::sctp_network_connector_config e2_du_nw_config = generate_e2ap_nw_config(gnb_cfg, E2_DU_PPID); @@ -390,13 +388,6 @@ int main(int argc, char** argv) // Create E2AP GW remote connector. e2_gateway_remote_connector e2_gw{*epoll_broker, e2_du_nw_config, *du_pcaps.e2ap}; - // Create CU-CP config. - cu_cp_build_dependencies cu_cp_dependencies; - cu_cp_dependencies.cu_cp_executor = workers.cu_cp_exec; - cu_cp_dependencies.cu_cp_e2_exec = workers.cu_cp_e2_exec; - cu_cp_dependencies.n2_client = n2_client.get(); - cu_cp_dependencies.timers = cu_timers; - // create CU-CP. auto cu_cp_obj_and_cmds = build_cu_cp(cu_cp_config, cu_cp_dependencies); @@ -453,7 +444,7 @@ int main(int argc, char** argv) cu_cp_obj.start(); gnb_logger.info("CU-CP started successfully"); - if (not cu_cp_obj.get_ng_handler().amf_is_connected()) { + if (not cu_cp_obj.get_ng_handler().amfs_are_connected()) { report_error("CU-CP failed to connect to AMF"); } diff --git a/apps/gnb/gnb_appconfig_validators.cpp b/apps/gnb/gnb_appconfig_validators.cpp index c527ce42d1..1b202c6437 100644 --- a/apps/gnb/gnb_appconfig_validators.cpp +++ b/apps/gnb/gnb_appconfig_validators.cpp @@ -46,11 +46,25 @@ bool srsran::validate_appconfig(const gnb_appconfig& config) bool srsran::validate_plmn_and_tacs(const du_high_unit_config& du_hi_cfg, const cu_cp_unit_config& cu_cp_cfg) { + std::vector supported_tas; + + for (const auto& supported_ta : cu_cp_cfg.amf_config.amf.supported_tas) { + supported_tas.push_back(supported_ta); + } + + for (const auto& amf : cu_cp_cfg.extra_amfs) { + for (const auto& supported_ta : amf.supported_tas) { + supported_tas.push_back(supported_ta); + } + } + bool ret_val = false; for (const auto& cell : du_hi_cfg.cells_cfg) { - for (const auto& supported_ta : cu_cp_cfg.supported_tas) { - if (supported_ta.tac == cell.cell.tac && supported_ta.plmn == cell.cell.plmn) { - ret_val = true; + for (const auto& supported_ta : supported_tas) { + for (const auto& plmn_item : supported_ta.plmn_list) { + if (plmn_item.plmn_id == cell.cell.plmn && supported_ta.tac == cell.cell.tac) { + ret_val = true; + } } } diff --git a/apps/units/cu_cp/cu_cp_builder.cpp b/apps/units/cu_cp/cu_cp_builder.cpp index a499d42b4b..b8744e891c 100644 --- a/apps/units/cu_cp/cu_cp_builder.cpp +++ b/apps/units/cu_cp/cu_cp_builder.cpp @@ -24,9 +24,12 @@ cu_cp_unit srsran::build_cu_cp(const cu_cp_unit_config& cu_cp_unit_cfg, cu_cp_bu srs_cu_cp::cu_cp_configuration cu_cp_cfg = generate_cu_cp_config(cu_cp_unit_cfg); cu_cp_cfg.services.cu_cp_executor = dependencies.cu_cp_executor; cu_cp_cfg.services.cu_cp_e2_exec = dependencies.cu_cp_e2_exec; - cu_cp_cfg.services.n2_gw = dependencies.n2_client; cu_cp_cfg.services.timers = dependencies.timers; + for (unsigned pos = 0; pos < dependencies.n2_clients.size(); pos++) { + cu_cp_cfg.ngaps[pos].n2_gw = dependencies.n2_clients[pos].get(); + } + cu_cp_unit cu_cmd_wrapper; cu_cmd_wrapper.unit = create_cu_cp(cu_cp_cfg); diff --git a/apps/units/cu_cp/cu_cp_builder.h b/apps/units/cu_cp/cu_cp_builder.h index 66bc666ac0..6dc94cf164 100644 --- a/apps/units/cu_cp/cu_cp_builder.h +++ b/apps/units/cu_cp/cu_cp_builder.h @@ -24,10 +24,10 @@ class n2_connection_client; /// CU-CP build dependencies. struct cu_cp_build_dependencies { - task_executor* cu_cp_executor = nullptr; - task_executor* cu_cp_e2_exec = nullptr; - srs_cu_cp::n2_connection_client* n2_client = nullptr; - timer_manager* timers = nullptr; + task_executor* cu_cp_executor = nullptr; + task_executor* cu_cp_e2_exec = nullptr; + std::vector> n2_clients; + timer_manager* timers = nullptr; }; /// Wraps the CU-CP and its supported application commands. diff --git a/apps/units/cu_cp/cu_cp_config_translators.cpp b/apps/units/cu_cp/cu_cp_config_translators.cpp index d2ae9a5963..c1f48836ad 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.cpp +++ b/apps/units/cu_cp/cu_cp_config_translators.cpp @@ -328,14 +328,32 @@ srs_cu_cp::cu_cp_configuration srsran::generate_cu_cp_config(const cu_cp_unit_co out_cfg.node.gnb_id = cu_cfg.gnb_id; out_cfg.node.ran_node_name = cu_cfg.ran_node_name; - if (!cu_cfg.supported_tas.empty()) { - // Clear default supported TAs if any are provided in the config. - out_cfg.node.supported_tas.clear(); + { + std::vector supported_tas; + for (const auto& supported_ta : cu_cfg.amf_config.amf.supported_tas) { + std::vector plmn_list; + for (const auto& plmn_item : supported_ta.plmn_list) { + expected plmn = plmn_identity::parse(plmn_item.plmn_id); + srsran_assert(plmn.has_value(), "Invalid PLMN: {}", plmn_item.plmn_id); + plmn_list.push_back({plmn.value(), plmn_item.tai_slice_support_list}); + } + supported_tas.push_back({supported_ta.tac, plmn_list}); + } + out_cfg.ngaps.push_back(srs_cu_cp::cu_cp_configuration::ngap_params{nullptr, supported_tas}); } - for (const auto& supported_ta : cu_cfg.supported_tas) { - expected plmn = plmn_identity::parse(supported_ta.plmn); - srsran_assert(plmn.has_value(), "Invalid PLMN: {}", supported_ta.plmn); - out_cfg.node.supported_tas.push_back({supported_ta.tac, plmn.value(), supported_ta.tai_slice_support_list}); + + for (const auto& cfg : cu_cfg.extra_amfs) { + std::vector supported_tas; + for (const auto& supported_ta : cfg.supported_tas) { + std::vector plmn_list; + for (const auto& plmn_item : supported_ta.plmn_list) { + expected plmn = plmn_identity::parse(plmn_item.plmn_id); + srsran_assert(plmn.has_value(), "Invalid PLMN: {}", plmn_item.plmn_id); + plmn_list.push_back({plmn.value(), plmn_item.tai_slice_support_list}); + } + supported_tas.push_back({supported_ta.tac, plmn_list}); + } + out_cfg.ngaps.push_back(srs_cu_cp::cu_cp_configuration::ngap_params{nullptr, supported_tas}); } out_cfg.rrc.force_reestablishment_fallback = cu_cfg.rrc_config.force_reestablishment_fallback; @@ -427,15 +445,17 @@ srs_cu_cp::cu_cp_configuration srsran::generate_cu_cp_config(const cu_cp_unit_co return out_cfg; } -srs_cu_cp::n2_connection_client_config -srsran::generate_n2_client_config(const cu_cp_unit_amf_config& amf_cfg, dlt_pcap& pcap_writer, io_broker& broker) +srs_cu_cp::n2_connection_client_config srsran::generate_n2_client_config(bool no_core, + const cu_cp_unit_amf_config_item& amf_cfg, + dlt_pcap& pcap_writer, + io_broker& broker) { using no_core_mode_t = srs_cu_cp::n2_connection_client_config::no_core; using network_mode_t = srs_cu_cp::n2_connection_client_config::network; using ngap_mode_t = std::variant; - ngap_mode_t mode = amf_cfg.no_core ? ngap_mode_t{no_core_mode_t{}} : ngap_mode_t{network_mode_t{broker}}; - if (not amf_cfg.no_core) { + ngap_mode_t mode = no_core ? ngap_mode_t{no_core_mode_t{}} : ngap_mode_t{network_mode_t{broker}}; + if (not no_core) { network_mode_t& nw_mode = std::get(mode); nw_mode.amf_address = amf_cfg.ip_addr; nw_mode.amf_port = amf_cfg.port; diff --git a/apps/units/cu_cp/cu_cp_config_translators.h b/apps/units/cu_cp/cu_cp_config_translators.h index 5d3f50051e..4fa97739e0 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.h +++ b/apps/units/cu_cp/cu_cp_config_translators.h @@ -16,13 +16,15 @@ namespace srsran { struct cu_cp_unit_config; -struct cu_cp_unit_amf_config; +struct cu_cp_unit_amf_config_item; /// Converts and returns the given gnb application configuration to a CU-CP configuration. srs_cu_cp::cu_cp_configuration generate_cu_cp_config(const cu_cp_unit_config& cu_cfg); /// Converts CU-CP configuration into N2 connection client. -srs_cu_cp::n2_connection_client_config -generate_n2_client_config(const cu_cp_unit_amf_config& amf_cfg, dlt_pcap& pcap_writer, io_broker& broker); +srs_cu_cp::n2_connection_client_config generate_n2_client_config(bool no_core, + const cu_cp_unit_amf_config_item& amf_cfg, + dlt_pcap& pcap_writer, + io_broker& broker); } // namespace srsran diff --git a/apps/units/cu_cp/cu_cp_unit_config.h b/apps/units/cu_cp/cu_cp_unit_config.h index beaba9e031..28d25f0a61 100644 --- a/apps/units/cu_cp/cu_cp_unit_config.h +++ b/apps/units/cu_cp/cu_cp_unit_config.h @@ -21,19 +21,44 @@ namespace srsran { -struct cu_cp_unit_supported_ta_item { - unsigned tac; - std::string plmn; +struct cu_cp_unit_plmn_item { + std::string plmn_id; /// Supported Slices by the RAN node. std::vector tai_slice_support_list; }; +struct cu_cp_unit_supported_ta_item { + unsigned tac; + std::vector plmn_list; +}; + /// All tracking area related configuration parameters. struct cu_cp_unit_ta_config { /// List of all tracking areas supported by the CU-CP. std::vector supported_tas; }; +struct cu_cp_unit_amf_config_item { + std::string ip_addr = "127.0.0.1"; + uint16_t port = 38412; + std::string bind_addr = "127.0.0.1"; + std::string bind_interface = "auto"; + int sctp_rto_initial = 120; + int sctp_rto_min = 120; + int sctp_rto_max = 500; + int sctp_init_max_attempts = 3; + int sctp_max_init_timeo = 500; + bool sctp_nodelay = false; + /// List of all tracking areas supported by the AMF. + std::vector supported_tas; +}; + +struct cu_cp_unit_amf_config { + cu_cp_unit_amf_config_item amf; + /// Allow CU-CP to run without a core, e.g. for test mode. + bool no_core = false; +}; + /// Report configuration, for now only supporting the A3 event. struct cu_cp_unit_report_config { unsigned report_cfg_id; @@ -223,20 +248,6 @@ struct cu_cp_unit_metrics_config { unsigned cu_cp_statistics_report_period = 1; }; -struct cu_cp_unit_amf_config { - std::string ip_addr = "127.0.0.1"; - uint16_t port = 38412; - std::string bind_addr = "127.0.0.1"; - std::string bind_interface = "auto"; - int sctp_rto_initial = 120; - int sctp_rto_min = 120; - int sctp_rto_max = 500; - int sctp_init_max_attempts = 3; - int sctp_max_init_timeo = 500; - bool sctp_nodelay = false; - bool no_core = false; -}; - /// CU-CP application unit configuration. struct cu_cp_unit_config { /// Node name. @@ -260,9 +271,9 @@ struct cu_cp_unit_config { /// Metrics configuration. cu_cp_unit_metrics_config metrics; /// AMF configuration. - cu_cp_unit_amf_config amf_cfg; - /// List of all tracking areas supported by the CU-CP. - std::vector supported_tas; + cu_cp_unit_amf_config amf_config; + // List of all AMFs the CU-CP should connect to. + std::vector extra_amfs; /// Mobility configuration. cu_cp_unit_mobility_config mobility_config; /// RRC configuration. diff --git a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp index 52b57eeda6..844f89e2f8 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp +++ b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp @@ -52,6 +52,28 @@ static void configure_cli11_tai_slice_support_args(CLI::App& app, s_nssai_t& con add_option(app, "--sd", config.sd, "Service Differentiator")->capture_default_str()->check(CLI::Range(0, 0xffffff)); } +static void configure_cli11_plmn_item_args(CLI::App& app, cu_cp_unit_plmn_item& config) +{ + add_option(app, "--plmn", config.plmn_id, "PLMN to be configured"); + + // TAI slice support list. + app.add_option_function>( + "--tai_slice_support_list", + [&config](const std::vector& values) { + config.tai_slice_support_list.resize(values.size()); + + for (unsigned i = 0, e = values.size(); i != e; ++i) { + CLI::App subapp("TAI slice support list"); + subapp.config_formatter(create_yaml_config_parser()); + subapp.allow_config_extras(CLI::config_extras_mode::error); + configure_cli11_tai_slice_support_args(subapp, config.tai_slice_support_list[i]); + std::istringstream ss(values[i]); + subapp.parse_from_stream(ss); + } + }, + "Sets the list of TAI slices for this PLMN"); +} + static void configure_cli11_supported_ta_args(CLI::App& app, cu_cp_unit_supported_ta_item& config) { add_option(app, "--tac", config.tac, "TAC to be configured")->check([](const std::string& value) { @@ -66,24 +88,66 @@ static void configure_cli11_supported_ta_args(CLI::App& app, cu_cp_unit_supporte return (tac <= 0xffffffU) ? "" : "TAC value out of range"; }); - add_option(app, "--plmn", config.plmn, "PLMN to be configured"); - // TAI slice support list. + // PLMN item list. app.add_option_function>( - "--tai_slice_support_list", + "--plmn_list", [&config](const std::vector& values) { - config.tai_slice_support_list.resize(values.size()); + config.plmn_list.resize(values.size()); for (unsigned i = 0, e = values.size(); i != e; ++i) { - CLI::App subapp("TAI slice support list"); + CLI::App subapp("PLMN item list"); subapp.config_formatter(create_yaml_config_parser()); subapp.allow_config_extras(CLI::config_extras_mode::error); - configure_cli11_tai_slice_support_args(subapp, config.tai_slice_support_list[i]); + configure_cli11_plmn_item_args(subapp, config.plmn_list[i]); std::istringstream ss(values[i]); subapp.parse_from_stream(ss); } }, - "Sets the list of TAI slices supported by the CU-CP"); + "Sets the list of PLMN items for this tracking area"); +} + +static void configure_cli11_amf_item_args(CLI::App& app, cu_cp_unit_amf_config_item& config) +{ + add_option(app, "--addr", config.ip_addr, "AMF IP address"); + add_option(app, "--port", config.port, "AMF port")->capture_default_str()->check(CLI::Range(20000, 40000)); + add_option(app, "--bind_addr", config.bind_addr, "Local IP address to bind for N2 interface")->check(CLI::ValidIPV4); + add_option(app, "--bind_interface", config.bind_interface, "Network device to bind for N2 interface") + ->capture_default_str(); + add_option(app, "--sctp_rto_initial", config.sctp_rto_initial, "SCTP initial RTO value"); + add_option(app, "--sctp_rto_min", config.sctp_rto_min, "SCTP RTO min"); + add_option(app, "--sctp_rto_max", config.sctp_rto_max, "SCTP RTO max"); + add_option(app, "--sctp_init_max_attempts", config.sctp_init_max_attempts, "SCTP init max attempts"); + add_option(app, "--sctp_max_init_timeo", config.sctp_max_init_timeo, "SCTP max init timeout "); + add_option(app, + "--sctp_nodelay", + config.sctp_nodelay, + "Send SCTP messages as soon as possible without any Nagle-like algorithm"); + + // supported tracking areas configuration parameters. + app.add_option_function>( + "--supported_tracking_areas", + [&config](const std::vector& values) { + config.supported_tas.resize(values.size()); + + for (unsigned i = 0, e = values.size(); i != e; ++i) { + CLI::App subapp("Supported tracking areas of AMF"); + subapp.config_formatter(create_yaml_config_parser()); + subapp.allow_config_extras(CLI::config_extras_mode::error); + configure_cli11_supported_ta_args(subapp, config.supported_tas[i]); + std::istringstream ss(values[i]); + subapp.parse_from_stream(ss); + } + }, + "Sets the list of tracking areas supported by this AMF"); +} + +static void configure_cli11_amf_args(CLI::App& app, cu_cp_unit_amf_config& config) +{ + add_option(app, "--no_core", config.no_core, "Allow CU-CP to run without a core")->capture_default_str(); + + // AMF parameters. + configure_cli11_amf_item_args(app, config.amf); } static void configure_cli11_report_args(CLI::App& app, cu_cp_unit_report_config& report_params) @@ -310,23 +374,26 @@ static void configure_cli11_cu_cp_args(CLI::App& app, cu_cp_unit_config& cu_cp_p "seconds. The timeout must be larger than T310. If the value is reached, the UE will be released") ->capture_default_str(); - // Tracking areas section. - auto ta_lambda = [&cu_cp_params](const std::vector& values) { - // Prepare the supported TAs list. - cu_cp_params.supported_tas.resize(values.size()); + CLI::App* amf_subcmd = app.add_subcommand("amf", "AMF configuration"); + configure_cli11_amf_args(*amf_subcmd, cu_cp_params.amf_config); - // Format every TA setting. - for (unsigned i = 0, e = values.size(); i != e; ++i) { - CLI::App subapp("Supported tracking areas", "TA config, item #" + std::to_string(i)); - subapp.config_formatter(create_yaml_config_parser()); - subapp.allow_config_extras(CLI::config_extras_mode::capture); - configure_cli11_supported_ta_args(subapp, cu_cp_params.supported_tas[i]); - std::istringstream ss(values[i]); - subapp.parse_from_stream(ss); - } - }; - add_option_cell( - app, "--supported_tracking_areas", ta_lambda, "Configures the list of tracking areas supported by the CU-CP"); + // AMF parameters. + app.add_option_function>( + "--extra_amfs", + [&cu_cp_params](const std::vector& values) { + cu_cp_params.extra_amfs.resize(values.size()); + + for (unsigned i = 0, e = values.size(); i != e; ++i) { + CLI::App subapp("CU-CP AMF list"); + subapp.config_formatter(create_yaml_config_parser()); + subapp.allow_config_extras(CLI::config_extras_mode::error); + configure_cli11_amf_item_args(subapp, cu_cp_params.extra_amfs[i]); + std::istringstream ss(values[i]); + subapp.parse_from_stream(ss); + } + }, + "Sets the list of extra AMFs for the CU-CP to connect to") + ->group(""); CLI::App* mobility_subcmd = app.add_subcommand("mobility", "Mobility configuration"); configure_cli11_mobility_args(*mobility_subcmd, cu_cp_params.mobility_config); @@ -451,26 +518,6 @@ static void configure_cli11_metrics_args(CLI::App& app, cu_cp_unit_metrics_confi ->capture_default_str(); } -static void configure_cli11_amf_args(CLI::App& app, cu_cp_unit_amf_config& amf_params) -{ - add_option(app, "--addr", amf_params.ip_addr, "AMF IP address"); - add_option(app, "--port", amf_params.port, "AMF port")->capture_default_str()->check(CLI::Range(20000, 40000)); - add_option(app, "--bind_addr", amf_params.bind_addr, "Local IP address to bind for N2 interface") - ->check(CLI::ValidIPV4); - add_option(app, "--bind_interface", amf_params.bind_interface, "Network device to bind for N2 interface") - ->capture_default_str(); - add_option(app, "--sctp_rto_initial", amf_params.sctp_rto_initial, "SCTP initial RTO value"); - add_option(app, "--sctp_rto_min", amf_params.sctp_rto_min, "SCTP RTO min"); - add_option(app, "--sctp_rto_max", amf_params.sctp_rto_max, "SCTP RTO max"); - add_option(app, "--sctp_init_max_attempts", amf_params.sctp_init_max_attempts, "SCTP init max attempts"); - add_option(app, "--sctp_max_init_timeo", amf_params.sctp_max_init_timeo, "SCTP max init timeout"); - add_option(app, - "--sctp_nodelay", - amf_params.sctp_nodelay, - "Send SCTP messages as soon as possible without any Nagle-like algorithm"); - add_option(app, "--no_core", amf_params.no_core, "Allow gNB to run without a core"); -} - void srsran::configure_cli11_with_cu_cp_unit_config_schema(CLI::App& app, cu_cp_unit_config& unit_cfg) { add_option(app, "--gnb_id", unit_cfg.gnb_id.id, "gNodeB identifier")->capture_default_str(); @@ -478,9 +525,6 @@ void srsran::configure_cli11_with_cu_cp_unit_config_schema(CLI::App& app, cu_cp_ ->capture_default_str() ->check(CLI::Range(22, 32)); add_option(app, "--ran_node_name", unit_cfg.ran_node_name, "RAN node name")->capture_default_str(); - // AMF section. - CLI::App* amf_subcmd = add_subcommand(app, "amf", "AMF parameters")->configurable(); - configure_cli11_amf_args(*amf_subcmd, unit_cfg.amf_cfg); // CU-CP section CLI::App* cu_cp_subcmd = add_subcommand(app, "cu_cp", "CU-CP parameters")->configurable(); @@ -516,24 +560,9 @@ void srsran::configure_cli11_with_cu_cp_unit_config_schema(CLI::App& app, cu_cp_ add_option_cell(app, "--qos", qos_lambda, "Configures RLC and PDCP radio bearers on a per 5QI basis."); } -static std::vector auto_generate_supported_tas() -{ - std::vector vec = {{7, "00101", {{1}}}}; - return vec; -} - -void srsran::autoderive_cu_cp_parameters_after_parsing(CLI::App& app, - cu_cp_unit_config& unit_cfg, - std::vector supported_tas) +void srsran::autoderive_cu_cp_parameters_after_parsing(CLI::App& app, cu_cp_unit_config& unit_cfg) { auto cu_cp_app = app.get_subcommand_ptr("cu_cp"); - // No supported tracking areas defined in the cu_cp section. Use the given ones. - if (cu_cp_app->count_all() == 0 || cu_cp_app->count("--supported_tracking_areas") == 0) { - srsran_assert(unit_cfg.supported_tas.empty(), "Supported tracking area list is not empty"); - - unit_cfg.supported_tas = supported_tas.empty() ? auto_generate_supported_tas() : std::move(supported_tas); - } - for (auto& cell : unit_cfg.mobility_config.cells) { // Set gNB ID bit length of the neighbor cell to be equal to the current unit gNB ID bit length, if not explicitly // set. diff --git a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.h b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.h index e9f884b68a..1cb03e0849 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.h +++ b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.h @@ -22,9 +22,7 @@ struct cu_cp_unit_supported_ta_item; /// Configures the given CLI11 application with the CU-CP application unit configuration schema. void configure_cli11_with_cu_cp_unit_config_schema(CLI::App& app, cu_cp_unit_config& unit_cfg); -/// Auto derive DU high parameters after the parsing. -void autoderive_cu_cp_parameters_after_parsing(CLI::App& app, - cu_cp_unit_config& unit_cfg, - std::vector supported_tas); +/// Auto derive CU-CP parameters after the parsing. +void autoderive_cu_cp_parameters_after_parsing(CLI::App& app, cu_cp_unit_config& unit_cfg); } // namespace srsran diff --git a/apps/units/cu_cp/cu_cp_unit_config_validator.cpp b/apps/units/cu_cp/cu_cp_unit_config_validator.cpp index 38a2e9a77b..a3f84284fc 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_validator.cpp +++ b/apps/units/cu_cp/cu_cp_unit_config_validator.cpp @@ -432,34 +432,58 @@ static bool validate_qos_appconfig(span config) } /// Validates the given AMF configuration. Returns true on success, otherwise false. -static bool validate_amf_appconfig(const cu_cp_unit_amf_config& config) +static bool validate_amf_appconfig(const cu_cp_unit_amf_config& amf_config, + const std::vector& extra_amfs) { - // only check for non-empty AMF address and default port - if (config.ip_addr.empty() or config.port != 38412) { - return false; - } - return true; -} + std::vector plmns; -/// Validates the given supported tracking areas configuration. Returns true on success, otherwise false. -static bool validate_supported_tas_appconfig(const std::vector& config) -{ - if (config.size() > 1) { - for (unsigned outer_ta_idx = 0; outer_ta_idx < config.size(); outer_ta_idx++) { - for (unsigned inner_ta_idx = outer_ta_idx + 1; inner_ta_idx < config.size(); inner_ta_idx++) { - if (config[outer_ta_idx].plmn == config[inner_ta_idx].plmn && - config[outer_ta_idx].tac == config[inner_ta_idx].tac) { - fmt::print("Supported tracking areas must be unique\n"); - return false; + std::vector amfs; + + amfs.push_back(amf_config.amf); + + amfs.insert(amfs.end(), extra_amfs.begin(), extra_amfs.end()); + + for (const auto& config : amfs) { + // check for non-empty AMF address + if (config.ip_addr.empty()) { + return false; + } + + // check supported tracking areas + if (config.supported_tas.size() > 1) { + for (unsigned outer_ta_idx = 0; outer_ta_idx < config.supported_tas.size(); outer_ta_idx++) { + std::vector outer_plmns; + for (const auto& plmn_item : config.supported_tas[outer_ta_idx].plmn_list) { + outer_plmns.push_back(plmn_item.plmn_id); + } + + for (unsigned inner_ta_idx = outer_ta_idx + 1; inner_ta_idx < config.supported_tas.size(); inner_ta_idx++) { + if (config.supported_tas[outer_ta_idx].tac == config.supported_tas[inner_ta_idx].tac) { + for (const auto& plmn_item : config.supported_tas[inner_ta_idx].plmn_list) { + if (std::find(outer_plmns.begin(), outer_plmns.end(), plmn_item.plmn_id) != outer_plmns.end()) { + fmt::print("Supported tracking areas of a AMF must be unique\n"); + return false; + } + } + } } } } - } - for (const auto& ta : config) { - if (ta.tai_slice_support_list.empty()) { - fmt::print("TAI slice support list for PLMN={} and TAC={} is empty\n", ta.plmn, ta.tac); - return false; + for (const auto& ta : config.supported_tas) { + for (const auto& plmn_item : ta.plmn_list) { + if (std::find(plmns.begin(), plmns.end(), plmn_item.plmn_id) == plmns.end()) { + plmns.push_back(plmn_item.plmn_id); + } else { + fmt::print("PLMN={} is already supported by another AMF\n", plmn_item.plmn_id); + return false; + } + + if (plmn_item.tai_slice_support_list.empty()) { + fmt::print("TAI slice support list for PLMN={} and TAC={} is empty\n", plmn_item.plmn_id, ta.tac); + return false; + } + } } } @@ -469,12 +493,8 @@ static bool validate_supported_tas_appconfig(const std::vector& amfs) { YAML::Node node; - node["sst"] = config.sst; - if (config.sd) { - node["sd"] = config.sd.value(); + for (const auto& amf : amfs) { + node["extra_amfs"] = build_cu_cp_extra_amfs_item_section(amf); } return node; } -static YAML::Node build_cu_cp_supported_tas_section(const std::vector& config) +static YAML::Node build_cu_cp_amf_section(const cu_cp_unit_amf_config& config) { YAML::Node node; - for (const auto& supported_ta : config) { - node["tac"] = supported_ta.tac; - node["plmn"] = supported_ta.plmn; - for (const auto& slice : supported_ta.tai_slice_support_list) { - node["tai_slice_support_list"] = build_cu_cp_tai_slice_section(slice); - } - } + node["no_core"] = config.no_core; + node["amf"] = build_cu_cp_extra_amfs_item_section(config.amf); return node; } @@ -197,11 +234,12 @@ static YAML::Node build_cu_cp_section(const cu_cp_unit_config& config) node["inactivity_timer"] = config.inactivity_timer; node["pdu_session_setup_timeout"] = config.pdu_session_setup_timeout; - node["supported_tracking_areas"] = build_cu_cp_supported_tas_section(config.supported_tas); - node["mobility"] = build_cu_cp_mobility_section(config.mobility_config); - node["rrc"] = build_cu_cp_rrc_section(config.rrc_config); - node["security"] = build_cu_cp_security_section(config.security_config); - node["f1ap"] = build_cu_cp_f1ap_section(config.f1ap_config); + node["amf"] = build_cu_cp_amf_section(config.amf_config); + node["extra_amfs"] = build_cu_cp_extra_amfs_section(config.extra_amfs); + node["mobility"] = build_cu_cp_mobility_section(config.mobility_config); + node["rrc"] = build_cu_cp_rrc_section(config.rrc_config); + node["security"] = build_cu_cp_security_section(config.security_config); + node["f1ap"] = build_cu_cp_f1ap_section(config.f1ap_config); return node; } @@ -350,7 +388,6 @@ void srsran::fill_cu_cp_config_in_yaml_schema(YAML::Node& node, const cu_cp_unit node["gnb_id_bit_length"] = static_cast(config.gnb_id.bit_length); node["ran_node_name"] = config.ran_node_name; node["cu_cp"] = build_cu_cp_section(config); - fill_cu_cp_amf_section(node["amf"], config.amf_cfg); fill_cu_cp_log_section(node["log"], config.loggers); fill_cu_cp_pcap_section(node["pcap"], config.pcap_cfg); fill_cu_cp_metrics_section(node["metrics"], config.metrics); diff --git a/configs/amf.yml b/configs/amf.yml new file mode 100644 index 0000000000..1d9ea49e70 --- /dev/null +++ b/configs/amf.yml @@ -0,0 +1,13 @@ +# Example configuration file for AMF. + +cu_cp: + + amf: + addr: 127.0.1.100 + bind_addr: 127.0.10.2 + supported_tracking_areas: # List of tracking areas supported by this AMF. Note that the first PLMN is used for the Global RAN Node ID + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 diff --git a/configs/tracking_areas.yml b/configs/tracking_areas.yml deleted file mode 100644 index 7577039aff..0000000000 --- a/configs/tracking_areas.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Example configuration file for supported tracking areas. - -cu_cp: - supported_tracking_areas: - # List of all tracking areas supported by the CU-CP. - # Note that the first PLMN of this list is used for the Global RAN Node ID - - tac: 7 - plmn: "00101" - tai_slice_support_list: - - sst: 1 - sd: 1 - - sst: 2 - sd: 42 diff --git a/include/srsran/cu_cp/cu_cp_configuration.h b/include/srsran/cu_cp/cu_cp_configuration.h index 771f7122cd..86f2bc6801 100644 --- a/include/srsran/cu_cp/cu_cp_configuration.h +++ b/include/srsran/cu_cp/cu_cp_configuration.h @@ -22,11 +22,15 @@ namespace srs_cu_cp { class n2_connection_client; -struct supported_tracking_area { - unsigned tac; - plmn_identity plmn; +struct plmn_item { + plmn_identity plmn_id; /// Supported Slices by the RAN node. - std::vector supported_slices; + std::vector slice_support_list; +}; + +struct supported_tracking_area { + unsigned tac; + std::vector plmn_list; }; /// Parameters of the CU-CP that will reported to the 5G core. @@ -34,8 +38,6 @@ struct ran_node_configuration { /// The gNodeB identifier. gnb_id_t gnb_id{411, 22}; std::string ran_node_name = "srsgnb01"; - // Supported TAs in the NG RAN node. - std::vector supported_tas; }; struct mobility_configuration { @@ -54,10 +56,9 @@ struct cu_cp_configuration { unsigned max_nof_ues = 8192; }; struct service_params { - task_executor* cu_cp_executor = nullptr; - task_executor* cu_cp_e2_exec = nullptr; - n2_connection_client* n2_gw = nullptr; - timer_manager* timers = nullptr; + task_executor* cu_cp_executor = nullptr; + task_executor* cu_cp_e2_exec = nullptr; + timer_manager* timers = nullptr; }; struct ngap_params { diff --git a/include/srsran/cu_cp/cu_cp_configuration_helpers.h b/include/srsran/cu_cp/cu_cp_configuration_helpers.h index 15c442a935..370c77204a 100644 --- a/include/srsran/cu_cp/cu_cp_configuration_helpers.h +++ b/include/srsran/cu_cp/cu_cp_configuration_helpers.h @@ -146,8 +146,6 @@ inline std::map make_default_cu_cp_qos_c inline srs_cu_cp::cu_cp_configuration make_default_cu_cp_config() { srs_cu_cp::cu_cp_configuration cfg{}; - // Supported TAs (this default entry will be removed if supported TAs are provided in the config) - cfg.node.supported_tas.push_back(srsran::srs_cu_cp::supported_tracking_area{7, plmn_identity::test_value(), {{1}}}); // DRBs cfg.bearers.drb_config = config_helpers::make_default_cu_cp_qos_config_list(); // Security. @@ -190,13 +188,18 @@ inline bool is_valid_configuration(const srs_cu_cp::cu_cp_configuration& config) } inline std::vector -get_supported_plmns(const std::vector& supported_tas) +get_supported_plmns(const std::vector& ngaps) { std::vector plmns; - plmns.reserve(supported_tas.size()); - for (const auto& ta : supported_tas) { - plmns.push_back(ta.plmn); + + for (const auto& ngap : ngaps) { + for (const auto& ta : ngap.supported_tas) { + for (const auto& plmn_item : ta.plmn_list) { + plmns.push_back(plmn_item.plmn_id); + } + } } + return plmns; } diff --git a/include/srsran/cu_cp/cu_cp_ng_handler.h b/include/srsran/cu_cp/cu_cp_ng_handler.h index 08c4ab1694..0614ef0f08 100644 --- a/include/srsran/cu_cp/cu_cp_ng_handler.h +++ b/include/srsran/cu_cp/cu_cp_ng_handler.h @@ -11,6 +11,7 @@ #pragma once #include "srsran/ngap/ngap.h" +#include "srsran/ran/plmn_identity.h" namespace srsran { namespace srs_cu_cp { @@ -24,16 +25,13 @@ class cu_cp_ng_handler virtual ~cu_cp_ng_handler() = default; /// \brief Get the NG message handler interface. - /// \return The NG message handler interface. - virtual ngap_message_handler& get_ngap_message_handler() = 0; + /// \param[in] plmn The PLMN of the NGAP. + /// \return A pointer to the NG message handler interface if it was found, nullptr otherwise. + virtual ngap_message_handler* get_ngap_message_handler(const plmn_identity& plmn) = 0; - /// \brief Get the NG event handler interface. - /// \return The NG event handler interface. - virtual ngap_event_handler& get_ngap_event_handler() = 0; - - /// \brief Get the state of the AMF connection. - /// \return True if AMF is connected, false otherwise. - virtual bool amf_is_connected() = 0; + /// \brief Get the state of the AMF connections. + /// \return True if all AMFs are connected, false otherwise. + virtual bool amfs_are_connected() = 0; }; } // namespace srs_cu_cp diff --git a/include/srsran/cu_cp/cu_cp_types.h b/include/srsran/cu_cp/cu_cp_types.h index 764c344943..da209981a6 100644 --- a/include/srsran/cu_cp/cu_cp_types.h +++ b/include/srsran/cu_cp/cu_cp_types.h @@ -189,6 +189,7 @@ struct cu_cp_five_g_s_tmsi { struct cu_cp_initial_ue_message { ue_index_t ue_index = ue_index_t::invalid; + plmn_identity plmn = plmn_identity::test_value(); byte_buffer nas_pdu; establishment_cause_t establishment_cause; cu_cp_user_location_info_nr user_location_info; @@ -198,6 +199,7 @@ struct cu_cp_initial_ue_message { struct cu_cp_ul_nas_transport { ue_index_t ue_index = ue_index_t::invalid; + plmn_identity plmn = plmn_identity::test_value(); byte_buffer nas_pdu; cu_cp_user_location_info_nr user_location_info; }; diff --git a/include/srsran/ngap/ngap_configuration_helpers.h b/include/srsran/ngap/ngap_configuration_helpers.h index 4363334b7a..948daed255 100644 --- a/include/srsran/ngap/ngap_configuration_helpers.h +++ b/include/srsran/ngap/ngap_configuration_helpers.h @@ -18,17 +18,6 @@ namespace config_helpers { std::map make_default_ngap_qos_config_list(); -/// Generates default cell configuration used by gNB DU. The default configuration should be valid. -inline srs_cu_cp::ngap_configuration make_default_ngap_config() -{ - srs_cu_cp::ngap_configuration cfg{}; - cfg.gnb_id = {411, 22}; - cfg.ran_node_name = "srsgnb01"; - cfg.supported_tas = {{7, plmn_identity::test_value(), {}}}; - - return cfg; -} - /// Returns true if the given CU-CP configuration is valid, otherwise false. inline bool is_valid_configuration(const srs_cu_cp::ngap_configuration& config) { diff --git a/include/srsran/ngap/ngap_context.h b/include/srsran/ngap/ngap_context.h index 8fef75d969..20cba188f6 100644 --- a/include/srsran/ngap/ngap_context.h +++ b/include/srsran/ngap/ngap_context.h @@ -33,9 +33,10 @@ struct ngap_context_t { std::vector get_supported_plmns() const { std::vector supported_plmns; - supported_plmns.reserve(supported_tas.size()); for (const auto& ta : supported_tas) { - supported_plmns.push_back(ta.plmn); + for (const auto& plmn : ta.plmn_list) { + supported_plmns.push_back(plmn.plmn_id); + } } return supported_plmns; diff --git a/include/srsran/rrc/rrc_ue.h b/include/srsran/rrc/rrc_ue.h index b70233611c..c68417bbca 100644 --- a/include/srsran/rrc/rrc_ue.h +++ b/include/srsran/rrc/rrc_ue.h @@ -350,8 +350,9 @@ class rrc_ue_context_update_notifier virtual ~rrc_ue_context_update_notifier() = default; /// \brief Notifies that a new RRC UE needs to be setup. + /// \param[in] plmn The PLMN of the UE. /// \return True if the UE is accepted. - virtual bool on_ue_setup_request() = 0; + virtual bool on_ue_setup_request(plmn_identity plmn) = 0; /// \brief Notify about the reception of an RRC Reestablishment Request. /// \param[in] old_pci The old PCI contained in the RRC Reestablishment Request. diff --git a/lib/cu_cp/CMakeLists.txt b/lib/cu_cp/CMakeLists.txt index d6e1bb22bd..9265a932aa 100644 --- a/lib/cu_cp/CMakeLists.txt +++ b/lib/cu_cp/CMakeLists.txt @@ -28,6 +28,7 @@ set(SOURCES metrics_handler/metrics_handler_impl.cpp ngap_repository.cpp routines/amf_connection_setup_routine.cpp + routines/amf_connection_removal_routine.cpp routines/initial_context_setup_routine.cpp routines/pdu_session_routine_helpers.cpp routines/pdu_session_resource_setup_routine.cpp diff --git a/lib/cu_cp/adapters/rrc_ue_adapters.h b/lib/cu_cp/adapters/rrc_ue_adapters.h index db9b66a3b9..e8b79e1615 100644 --- a/lib/cu_cp/adapters/rrc_ue_adapters.h +++ b/lib/cu_cp/adapters/rrc_ue_adapters.h @@ -12,12 +12,14 @@ #include "../cu_cp_controller/cu_cp_ue_admission_controller.h" #include "../cu_cp_impl_interface.h" +#include "../ngap_repository.h" #include "../ue_manager/cu_cp_ue_impl_interface.h" #include "../up_resource_manager/up_resource_manager_impl.h" #include "srsran/adt/byte_buffer.h" #include "srsran/cu_cp/ue_task_scheduler.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" #include "srsran/ngap/ngap.h" +#include "srsran/ran/plmn_identity.h" #include "srsran/rrc/rrc_ue.h" namespace srsran { @@ -50,37 +52,33 @@ class rrc_ue_f1ap_pdu_adapter : public rrc_pdu_f1ap_notifier class rrc_ue_ngap_adapter : public rrc_ue_nas_notifier, public rrc_ue_control_notifier { public: - void connect_ngap(ngap_nas_message_handler& ngap_nas_msg_handler_, - ngap_control_message_handler& ngap_ctrl_msg_handler_) - { - ngap_nas_msg_handler = &ngap_nas_msg_handler_; - ngap_ctrl_msg_handler = &ngap_ctrl_msg_handler_; - } + explicit rrc_ue_ngap_adapter(ngap_repository& ngap_db_) : ngap_db(ngap_db_) {} void on_initial_ue_message(const cu_cp_initial_ue_message& msg) override { - srsran_assert(ngap_nas_msg_handler != nullptr, "NGAP handler must not be nullptr"); - ngap_nas_msg_handler->handle_initial_ue_message(msg); + auto* ngap = ngap_db.find_ngap(msg.plmn); + srsran_assert(ngap != nullptr, "NGAP for PLMN={} not found", msg.plmn); + ngap->get_ngap_nas_message_handler().handle_initial_ue_message(msg); } void on_ul_nas_transport_message(const cu_cp_ul_nas_transport& msg) override { - srsran_assert(ngap_nas_msg_handler != nullptr, "NGAP handler must not be nullptr"); - ngap_nas_msg_handler->handle_ul_nas_transport_message(msg); + auto* ngap = ngap_db.find_ngap(msg.plmn); + srsran_assert(ngap != nullptr, "NGAP for PLMN={} not found", msg.plmn); + ngap->get_ngap_nas_message_handler().handle_ul_nas_transport_message(msg); } void on_inter_cu_ho_rrc_recfg_complete_received(const ue_index_t ue_index, const nr_cell_global_id_t& cgi, const unsigned tac) override { - srsran_assert(ngap_ctrl_msg_handler != nullptr, "NGAP handler must not be nullptr"); - - ngap_ctrl_msg_handler->handle_inter_cu_ho_rrc_recfg_complete(ue_index, cgi, tac); + auto* ngap = ngap_db.find_ngap(cgi.plmn_id); + srsran_assert(ngap != nullptr, "NGAP for PLMN={} not found", cgi.plmn_id); + ngap->get_ngap_control_message_handler().handle_inter_cu_ho_rrc_recfg_complete(ue_index, cgi, tac); } private: - ngap_nas_message_handler* ngap_nas_msg_handler = nullptr; - ngap_control_message_handler* ngap_ctrl_msg_handler = nullptr; + ngap_repository& ngap_db; }; /// Adapter between RRC UE and CU-CP UE @@ -183,10 +181,10 @@ class rrc_ue_cu_cp_adapter : public rrc_ue_context_update_notifier, public rrc_u meas_handler = &meas_handler_; } - bool on_ue_setup_request() override + bool on_ue_setup_request(plmn_identity plmn) override { srsran_assert(controller != nullptr, "CU-CP controller must not be nullptr"); - return controller->request_ue_setup(); + return controller->request_ue_setup(plmn); } rrc_ue_reestablishment_context_response on_rrc_reestablishment_request(pci_t old_pci, rnti_t old_c_rnti) override diff --git a/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp b/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp index 3f6da23ac8..35192f4058 100644 --- a/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp +++ b/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp @@ -10,60 +10,129 @@ #include "amf_connection_manager.h" #include "../cu_cp_impl_interface.h" +#include "../routines/amf_connection_removal_routine.h" #include "../routines/amf_connection_setup_routine.h" #include "srsran/cu_cp/cu_cp_configuration.h" +#include "srsran/ngap/ngap.h" +#include "srsran/ran/plmn_identity.h" +#include using namespace srsran; using namespace srs_cu_cp; -amf_connection_manager::amf_connection_manager(common_task_scheduler& common_task_sched_, - ngap_connection_manager& ngap_conn_mng_) : - common_task_sched(common_task_sched_), ngap_conn_mng(ngap_conn_mng_) +amf_connection_manager::amf_connection_manager(ngap_repository& ngaps_, + task_executor& cu_cp_exec_, + common_task_scheduler& common_task_sched_) : + ngaps(ngaps_), + cu_cp_exec(cu_cp_exec_), + common_task_sched(common_task_sched_), + logger(srslog::fetch_basic_logger("CU-CP")) { } void amf_connection_manager::connect_to_amf(std::promise* completion_signal) { // Schedules setup routine to be executed in sequence with other CU-CP procedures. - common_task_sched.schedule_async_task( - launch_async([this, p = completion_signal](coro_context>& ctx) mutable { - CORO_BEGIN(ctx); + common_task_sched.schedule_async_task(launch_async([this, p = completion_signal]( + coro_context>& ctx) mutable { + CORO_BEGIN(ctx); - // Launch procedure to initiate AMF connection. - CORO_AWAIT_VALUE(bool success, launch_async(ngap_conn_mng)); + // Launch procedure to initiate AMF connection. + amfs_connected.emplace(ngaps.get_ngaps().begin()->first, false); + CORO_AWAIT_VALUE(bool success, launch_async(ngaps, amfs_connected.begin()->second)); - // Handle result of NG setup. - handle_connection_setup_result(success); + // Signal through the promise the result of the connection setup. + if (p != nullptr) { + p->set_value(success); + } - // Signal through the promise the result of the connection setup. - if (p != nullptr) { - p->set_value(success); - } + CORO_RETURN(); + })); +} + +async_task amf_connection_manager::disconnect_amf() +{ + if (ngaps.get_ngaps().empty() or amfs_connected.empty()) { + logger.error("No NGAP interface available to disconnect from AMF"); + return launch_async([](coro_context>& ctx) { + CORO_BEGIN(ctx); + CORO_RETURN(); + }); + } - CORO_RETURN(); - })); + return launch_async(ngaps.get_ngaps().begin()->second, + amfs_connected.begin()->second); } -async_task amf_connection_manager::stop() +void amf_connection_manager::stop() { - return launch_async([this](coro_context>& ctx) mutable { - CORO_BEGIN(ctx); + // Stop and delete AMF connections. + while (not cu_cp_exec.defer([this]() mutable { + common_task_sched.schedule_async_task(launch_async([this](coro_context>& ctx) { + CORO_BEGIN(ctx); + // Disconnect AMF connection. + CORO_AWAIT(disconnect_amf()); - // Run NG Removal procedure. - // TODO + // AMF disconnection successfully finished. + // Dispatch main async task loop destruction via defer so that the current coroutine ends successfully. + while (not cu_cp_exec.defer([this]() { + std::lock_guard lock(stop_mutex); + stop_completed = true; + stop_cvar.notify_one(); + })) { + logger.warning("Unable to stop AMF Manager. Retrying..."); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } - // Launch procedure to remove AMF connection. - CORO_AWAIT(ngap_conn_mng.handle_amf_disconnection_request()); + CORO_RETURN(); + })); + })) { + logger.warning("Failed to dispatch AMF stop task. Retrying..."); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } - // Update AMF connection handler state. - amf_connected = false; + // Wait for AMF stop to complete. + { + std::unique_lock lock(stop_mutex); + stop_cvar.wait(lock, [this] { return stop_completed; }); + } +} - CORO_RETURN(); - }); +bool amf_connection_manager::is_amf_connected(plmn_identity plmn) const +{ + amf_index_t amf_index = plmn_to_amf_index(plmn); + if (amf_index == amf_index_t::invalid) { + return false; + } + + return is_amf_connected(amf_index); +} + +bool amf_connection_manager::is_amf_connected(amf_index_t amf_index) const +{ + const auto& amf_connected = amfs_connected.find(amf_index); + if (amf_connected == amfs_connected.end()) { + return false; + } + + return amf_connected->second.load(std::memory_order_relaxed); } -void amf_connection_manager::handle_connection_setup_result(bool success) +void amf_connection_manager::handle_connection_setup_result(amf_index_t amf_index, bool success) { // Update AMF connection handler state. - amf_connected = success; + amfs_connected.emplace(amf_index, success); +} + +amf_index_t amf_connection_manager::plmn_to_amf_index(plmn_identity plmn) const +{ + for (const auto& [amf_index, ngap] : ngaps.get_ngaps()) { + for (auto& supported_plmn : ngap->get_ngap_context().get_supported_plmns()) { + if (plmn == supported_plmn) { + return amf_index; + } + } + } + + return amf_index_t::invalid; } diff --git a/lib/cu_cp/cu_cp_controller/amf_connection_manager.h b/lib/cu_cp/cu_cp_controller/amf_connection_manager.h index dbc1588c4d..5d0058cddd 100644 --- a/lib/cu_cp/cu_cp_controller/amf_connection_manager.h +++ b/lib/cu_cp/cu_cp_controller/amf_connection_manager.h @@ -10,8 +10,10 @@ #pragma once +#include "../ngap_repository.h" #include "common_task_scheduler.h" #include "srsran/cu_cp/cu_cp.h" +#include "srsran/ran/plmn_identity.h" #include namespace srsran { @@ -23,7 +25,9 @@ struct cu_cp_configuration; class amf_connection_manager { public: - amf_connection_manager(common_task_scheduler& common_task_sched_, ngap_connection_manager& ngap_conn_mng_); + amf_connection_manager(ngap_repository& ngaps_, + task_executor& cu_cp_exec_, + common_task_scheduler& common_task_sched_); /// \brief Initiates the connection to the AMF. /// A promise is passed as a parameter to enable blocking synchronization between the completion of the scheduled @@ -31,18 +35,29 @@ class amf_connection_manager void connect_to_amf(std::promise* completion_signal = nullptr); /// \brief Initiate procedure to disconnect from the N2 interface. - async_task stop(); + async_task disconnect_amf(); + + void stop(); /// Checks whether the CU-CP is connected to the AMF. - bool is_amf_connected() const { return amf_connected.load(std::memory_order_relaxed); } + bool is_amf_connected(plmn_identity plmn) const; + bool is_amf_connected(amf_index_t amf_index) const; private: - void handle_connection_setup_result(bool success); + void handle_connection_setup_result(amf_index_t amf_index, bool success); + amf_index_t plmn_to_amf_index(plmn_identity plmn) const; + + ngap_repository& ngaps; + task_executor& cu_cp_exec; + common_task_scheduler& common_task_sched; + srslog::basic_logger& logger; - common_task_scheduler& common_task_sched; - ngap_connection_manager& ngap_conn_mng; + std::unordered_map> amfs_connected; - std::atomic amf_connected{false}; + std::atomic stopped{false}; + std::mutex stop_mutex; + std::condition_variable stop_cvar; + bool stop_completed = false; }; } // namespace srs_cu_cp diff --git a/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp b/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp index 5a34350be4..705e6951cc 100644 --- a/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp +++ b/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp @@ -18,15 +18,14 @@ using namespace srs_cu_cp; cu_cp_controller::cu_cp_controller(const cu_cp_configuration& config_, common_task_scheduler& common_task_sched_, - ngap_connection_manager& ngap_conn_mng_, + ngap_repository& ngaps_, cu_up_processor_repository& cu_ups_, du_processor_repository& dus_, task_executor& ctrl_exec_) : cfg(config_), - common_task_sched(common_task_sched_), ctrl_exec(ctrl_exec_), logger(srslog::fetch_basic_logger("CU-CP")), - amf_mng(common_task_sched_, ngap_conn_mng_), + amf_mng(ngaps_, ctrl_exec_, common_task_sched_), du_mng(cfg.admission.max_nof_dus, dus_, ctrl_exec, common_task_sched_), cu_up_mng(cfg.admission.max_nof_cu_ups, cu_ups_, ctrl_exec, common_task_sched_) { @@ -48,52 +47,27 @@ void cu_cp_controller::stop() // Stop and delete CU-UP connections. cu_up_mng.stop(); - // Stop AMF connection. - while (not ctrl_exec.defer([this]() { stop_impl(); })) { - logger.warning("Failed to dispatch CU-CP stop task. Retrying..."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - // Wait for stop_impl() to signal completion. - std::unique_lock lock(mutex); - cvar.wait(lock, [this]() { return not running; }); -} - -void cu_cp_controller::stop_impl() -{ - common_task_sched.schedule_async_task(launch_async([this](coro_context>& ctx) { - CORO_BEGIN(ctx); - - // Stop AMF connection. - CORO_AWAIT(amf_mng.stop()); - - // CU-CP stop successfully finished. - // Dispatch main async task loop destruction via defer so that the current coroutine ends successfully. - while (not ctrl_exec.defer([this]() { - std::lock_guard lock(mutex); - running = false; - cvar.notify_one(); - })) { - logger.warning("Unable to stop DU Manager. Retrying..."); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - CORO_RETURN(); - })); + // Stop and delete AMF connections. + amf_mng.stop(); } bool cu_cp_controller::handle_du_setup_request(du_index_t du_idx, const du_setup_request& req) { - if (not amf_mng.is_amf_connected()) { - // If AMF is not connected, it either means that the CU-CP is not operational state or there is a CU-CP failure. - return false; + bool success = false; + for (const auto& cell : req.gnb_du_served_cells_list) { + if (amf_mng.is_amf_connected(cell.served_cell_info.nr_cgi.plmn_id)) { + success = true; + } } - return true; + + // If AMF is not connected, it either means that the CU-CP is not operational state, there is a CU-CP failure or no + // AMF for the PLMN of the DU cells was found. + return success; } -bool cu_cp_controller::request_ue_setup() const +bool cu_cp_controller::request_ue_setup(plmn_identity plmn) const { - if (not amf_mng.is_amf_connected()) { + if (not amf_mng.is_amf_connected(plmn)) { return false; } diff --git a/lib/cu_cp/cu_cp_controller/cu_cp_controller.h b/lib/cu_cp/cu_cp_controller/cu_cp_controller.h index 3ea4eda6dd..92a99eeaba 100644 --- a/lib/cu_cp/cu_cp_controller/cu_cp_controller.h +++ b/lib/cu_cp/cu_cp_controller/cu_cp_controller.h @@ -10,6 +10,7 @@ #pragma once +#include "../ngap_repository.h" #include "amf_connection_manager.h" #include "cu_cp_ue_admission_controller.h" #include "cu_up_connection_manager.h" @@ -36,7 +37,7 @@ class cu_cp_controller : public cu_cp_ue_admission_controller public: cu_cp_controller(const cu_cp_configuration& config_, common_task_scheduler& common_task_sched_, - ngap_connection_manager& ngap_conn_mng_, + ngap_repository& ngaps_, cu_up_processor_repository& cu_ups_, du_processor_repository& dus_, task_executor& ctrl_exec); @@ -47,17 +48,14 @@ class cu_cp_controller : public cu_cp_ue_admission_controller bool handle_du_setup_request(du_index_t du_idx, const du_setup_request& req); - /// \brief Determines whether the CU-CP should accept a new UE connection. - bool request_ue_setup() const override; + /// \brief Determines whether the CU-CP should accept a new UE connection for a given PLMN. + bool request_ue_setup(plmn_identity plmn) const override; cu_cp_f1c_handler& get_f1c_handler() { return du_mng; } cu_cp_e1_handler& get_e1_handler() { return cu_up_mng; } private: - void stop_impl(); - const cu_cp_configuration& cfg; - common_task_scheduler& common_task_sched; task_executor& ctrl_exec; srslog::basic_logger& logger; @@ -65,9 +63,8 @@ class cu_cp_controller : public cu_cp_ue_admission_controller du_connection_manager du_mng; cu_up_connection_manager cu_up_mng; - std::mutex mutex; - std::condition_variable cvar; - bool running = true; + std::mutex mutex; + bool running = true; }; } // namespace srs_cu_cp diff --git a/lib/cu_cp/cu_cp_controller/cu_cp_ue_admission_controller.h b/lib/cu_cp/cu_cp_controller/cu_cp_ue_admission_controller.h index fcc60af980..bbc3be8ecc 100644 --- a/lib/cu_cp/cu_cp_controller/cu_cp_ue_admission_controller.h +++ b/lib/cu_cp/cu_cp_controller/cu_cp_ue_admission_controller.h @@ -10,6 +10,8 @@ #pragma once +#include "srsran/ran/plmn_identity.h" + namespace srsran { namespace srs_cu_cp { @@ -18,8 +20,8 @@ class cu_cp_ue_admission_controller public: virtual ~cu_cp_ue_admission_controller() = default; - /// Determines whether the CU-CP is in a condition to accept new UEs. - virtual bool request_ue_setup() const = 0; + /// Determines whether the CU-CP is in a condition to accept new UEs for a given PLMN. + virtual bool request_ue_setup(plmn_identity plmn) const = 0; }; } // namespace srs_cu_cp diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index e108be01fe..65e3046405 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -25,7 +25,6 @@ #include "routines/ue_transaction_info_release_routine.h" #include "srsran/cu_cp/cu_cp_types.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" -#include "srsran/ngap/ngap_factory.h" #include "srsran/rrc/rrc_du.h" #include #include @@ -37,23 +36,16 @@ using namespace srs_cu_cp; static void assert_cu_cp_configuration_valid(const cu_cp_configuration& cfg) { srsran_assert(cfg.services.cu_cp_executor != nullptr, "Invalid CU-CP executor"); - srsran_assert(cfg.services.n2_gw != nullptr, "Invalid N2 GW client handler"); + srsran_assert(!cfg.ngaps.empty(), "No NGAPs configured"); + for (const auto& ngap : cfg.ngaps) { + srsran_assert(ngap.n2_gw != nullptr, "Invalid N2 GW client handler"); + } srsran_assert(cfg.services.timers != nullptr, "Invalid timers"); report_error_if_not(cfg.admission.max_nof_dus <= MAX_NOF_DUS, "Invalid max number of DUs"); report_error_if_not(cfg.admission.max_nof_cu_ups <= MAX_NOF_CU_UPS, "Invalid max number of CU-UPs"); } -ngap_configuration create_ngap_cfg(const cu_cp_configuration& cfg) -{ - ngap_configuration ngap_cfg; - ngap_cfg.gnb_id = cfg.node.gnb_id; - ngap_cfg.ran_node_name = cfg.node.ran_node_name; - ngap_cfg.supported_tas = cfg.node.supported_tas; - ngap_cfg.pdu_session_setup_timeout = cfg.ue.pdu_session_setup_timeout; - return ngap_cfg; -} - cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : cfg(config_), ue_mng(cfg), @@ -71,6 +63,8 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : srslog::fetch_basic_logger("CU-CP")}), cu_up_db(cu_up_repository_config{cfg, e1ap_ev_notifier, srslog::fetch_basic_logger("CU-CP")}), paging_handler(du_db), + ngap_db(ngap_repository_config{cfg, get_cu_cp_ngap_handler(), paging_handler, srslog::fetch_basic_logger("CU-CP")}), + rrc_ue_ngap_notifier(ngap_db), metrics_hdlr( std::make_unique(*cfg.services.cu_cp_executor, *cfg.services.timers, ue_mng, du_db)) { @@ -82,28 +76,12 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : e1ap_ev_notifier.connect_cu_cp(get_cu_cp_e1ap_handler()); rrc_du_cu_cp_notifier.connect_cu_cp(get_cu_cp_measurement_config_handler()); - // Create NGAP. - ngap_entity = create_ngap(create_ngap_cfg(cfg), - ngap_cu_cp_ev_notifier, - *cfg.services.n2_gw, - *cfg.services.timers, - *cfg.services.cu_cp_executor); - rrc_ue_ngap_notifier.connect_ngap(ngap_entity->get_ngap_nas_message_handler(), - ngap_entity->get_ngap_control_message_handler()); - - controller = std::make_unique(cfg, - common_task_sched, - ngap_entity->get_ngap_connection_manager(), - cu_up_db, - du_db, - *cfg.services.cu_cp_executor); + controller = std::make_unique( + cfg, common_task_sched, ngap_db, cu_up_db, du_db, *cfg.services.cu_cp_executor); conn_notifier.connect_node_connection_handler(*controller); - mobility_mng = create_mobility_manager(cfg.mobility.mobility_manager_config, - mobility_manager_ev_notifier, - ngap_entity->get_ngap_control_message_handler(), - du_db, - ue_mng); + mobility_mng = create_mobility_manager( + cfg.mobility.mobility_manager_config, mobility_manager_ev_notifier, ngap_db, du_db, ue_mng); cell_meas_ev_notifier.connect_mobility_manager(*mobility_mng); // Start statistics report timer @@ -127,7 +105,7 @@ bool cu_cp_impl::start() // start AMF connection procedure. controller->amf_connection_handler().connect_to_amf(&p); })) { - report_fatal_error("Failed to initiate CU-CP setup."); + report_fatal_error("Failed to initiate CU-CP setup"); } // Block waiting for CU-CP setup to complete. @@ -156,15 +134,21 @@ void cu_cp_impl::stop() logger.info("CU-CP stopped successfully."); } -ngap_message_handler& cu_cp_impl::get_ngap_message_handler() +ngap_message_handler* cu_cp_impl::get_ngap_message_handler(const plmn_identity& plmn) { - return *ngap_entity; + return ngap_db.find_ngap(plmn); }; -ngap_event_handler& cu_cp_impl::get_ngap_event_handler() +bool cu_cp_impl::amfs_are_connected() { - return *ngap_entity; -} + for (const auto& [amf_index, ngap] : ngap_db.get_ngaps()) { + if (not controller->amf_connection_handler().is_amf_connected(amf_index)) { + return false; + } + } + + return true; +}; void cu_cp_impl::handle_bearer_context_inactivity_notification(const cu_cp_inactivity_notification& msg) { @@ -309,9 +293,14 @@ async_task cu_cp_impl::handle_ue_context_transfer(ue_index_t ue_index, ue_ } } + auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + if (ngap == nullptr) { + logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); + return false; + } + // Transfer NGAP UE Context to new UE and remove the old context - if (not ngap_entity->update_ue_index( - ue_index, old_ue_index, ue_mng.find_ue(ue_index)->get_ngap_cu_cp_ue_notifier())) { + if (not ngap->update_ue_index(ue_index, old_ue_index, ue_mng.find_ue(ue_index)->get_ngap_cu_cp_ue_notifier())) { return false; } @@ -379,9 +368,16 @@ void cu_cp_impl::handle_handover_ue_context_push(ue_index_t source_ue_index, ue_ uint_to_cu_up_index(0)); srsran_assert(ue_mng.find_ue(target_ue_index) != nullptr, "ue={} not found", target_ue_index); + auto* ue = ue_mng.find_ue(target_ue_index); + + auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + if (ngap == nullptr) { + logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); + return; + } + // Transfer NGAP UE Context to new UE and remove the old context - if (!ngap_entity->update_ue_index( - target_ue_index, source_ue_index, ue_mng.find_ue(target_ue_index)->get_ngap_cu_cp_ue_notifier())) { + if (!ngap->update_ue_index(target_ue_index, source_ue_index, ue->get_ngap_cu_cp_ue_notifier())) { return; } // Transfer E1AP UE Context to new UE and remove old context @@ -390,8 +386,26 @@ void cu_cp_impl::handle_handover_ue_context_push(ue_index_t source_ue_index, ue_ async_task cu_cp_impl::handle_ue_context_release(const cu_cp_ue_context_release_request& request) { + auto* ue = ue_mng.find_ue(request.ue_index); + if (ue == nullptr) { + logger.warning("ue={}: Could not find UE", request.ue_index); + return launch_async([](coro_context>& ctx) { + CORO_BEGIN(ctx); + CORO_RETURN(); + }); + } + + auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + if (ngap == nullptr) { + logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); + return launch_async([](coro_context>& ctx) { + CORO_BEGIN(ctx); + CORO_RETURN(); + }); + } + return launch_async( - request, ngap_entity->get_ngap_control_message_handler(), *this, logger); + request, ngap->get_ngap_control_message_handler(), *this, logger); } bool cu_cp_impl::handle_handover_request(ue_index_t ue_index, security::security_context sec_ctxt) @@ -412,9 +426,19 @@ cu_cp_impl::handle_new_initial_context_setup_request(const ngap_init_context_set rrc_ue_interface* rrc_ue = ue->get_rrc_ue(); srsran_assert(rrc_ue != nullptr, "ue={}: Could not find RRC UE", request.ue_index); + auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + if (ngap == nullptr) { + logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); + return launch_async( + [](coro_context>>& ctx) { + CORO_BEGIN(ctx); + CORO_RETURN(make_unexpected(ngap_init_context_setup_failure{})); + }); + } + return launch_async(request, *rrc_ue, - ngap_entity->get_ngap_ue_radio_cap_management_handler(), + ngap->get_ngap_ue_radio_cap_management_handler(), ue->get_security_manager(), du_db.get_du_processor(ue->get_du_index()).get_f1ap_handler(), get_cu_cp_ngap_handler(), @@ -623,8 +647,9 @@ async_task cu_cp_impl::handle_ue_removal_request(ue_index_t ue_index) CORO_RETURN(); }); } + auto* ue = ue_mng.find_ue(ue_index); - du_index_t du_index = ue_mng.find_du_ue(ue_index)->get_du_index(); + du_index_t du_index = ue->get_du_index(); cu_up_index_t cu_up_index = uint_to_cu_up_index(0); // TODO: Update when mapping from UE index to CU-UP exists e1ap_bearer_context_removal_handler* e1ap_removal_handler = nullptr; @@ -632,11 +657,20 @@ async_task cu_cp_impl::handle_ue_removal_request(ue_index_t ue_index) e1ap_removal_handler = &cu_up_db.find_cu_up_processor(cu_up_index)->get_e1ap_bearer_context_removal_handler(); } + auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + if (ngap == nullptr) { + logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); + return launch_async([](coro_context>& ctx) { + CORO_BEGIN(ctx); + CORO_RETURN(); + }); + } + return launch_async(ue_index, du_db.get_du_processor(du_index).get_rrc_du_handler(), e1ap_removal_handler, du_db.get_du_processor(du_index).get_f1ap_handler(), - ngap_entity->get_ngap_ue_context_removal_handler(), + ngap->get_ngap_ue_context_removal_handler(), ue_mng, logger); } @@ -712,7 +746,7 @@ void cu_cp_impl::on_statistics_report_timer_expired() unsigned nof_rrc_ues = du_db.get_nof_rrc_ues(); // Get number of NGAP UEs - unsigned nof_ngap_ues = ngap_entity->get_ngap_statistics_handler().get_nof_ues(); + unsigned nof_ngap_ues = ngap_db.get_nof_ngap_ues(); // Get number of E1AP UEs unsigned nof_e1ap_ues = cu_up_db.get_nof_e1ap_ues(); diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index 8b3f1ec1fb..060f69d65e 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -21,10 +21,12 @@ #include "cu_cp_impl_interface.h" #include "cu_up_processor/cu_up_processor_repository.h" #include "du_processor/du_processor_repository.h" +#include "ngap_repository.h" #include "ue_manager/ue_manager_impl.h" #include "srsran/cu_cp/cu_cp_configuration.h" #include "srsran/cu_cp/cu_cp_types.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" +#include "srsran/ran/plmn_identity.h" #include #include @@ -56,10 +58,9 @@ class cu_cp_impl final : public cu_cp, void stop() override; // NGAP interface - ngap_message_handler& get_ngap_message_handler() override; - ngap_event_handler& get_ngap_event_handler() override; + ngap_message_handler* get_ngap_message_handler(const plmn_identity& plmn) override; - bool amf_is_connected() override { return controller->amf_connection_handler().is_amf_connected(); }; + bool amfs_are_connected() override; // CU-UP handler void handle_bearer_context_inactivity_notification(const cu_cp_inactivity_notification& msg) override; @@ -155,8 +156,6 @@ class cu_cp_impl final : public cu_cp, srslog::basic_logger& logger = srslog::fetch_basic_logger("CU-CP"); // Components - std::unique_ptr ngap_entity; - ue_manager ue_mng; std::unique_ptr mobility_mng; @@ -183,9 +182,6 @@ class cu_cp_impl final : public cu_cp, // RRC DU to CU-CP adapters rrc_du_cu_cp_adapter rrc_du_cu_cp_notifier; - // RRC UE to NGAP adapter - rrc_ue_ngap_adapter rrc_ue_ngap_notifier; - // DU connections being managed by the CU-CP. du_processor_repository du_db; @@ -195,6 +191,12 @@ class cu_cp_impl final : public cu_cp, // Handler of paging messages. paging_message_handler paging_handler; + // AMF connections beeing managed by the CU-CP. + ngap_repository ngap_db; + + // RRC UE to NGAP adapter + rrc_ue_ngap_adapter rrc_ue_ngap_notifier; + // Handler of the CU-CP connections to other remote nodes (e.g. AMF, CU-UPs, DUs). std::unique_ptr controller; diff --git a/lib/cu_cp/du_processor/du_processor_repository.cpp b/lib/cu_cp/du_processor/du_processor_repository.cpp index 6d685e9af6..43fa162a2d 100644 --- a/lib/cu_cp/du_processor/du_processor_repository.cpp +++ b/lib/cu_cp/du_processor/du_processor_repository.cpp @@ -22,9 +22,7 @@ using namespace srsran; using namespace srs_cu_cp; du_processor_repository::du_processor_repository(du_repository_config cfg_) : - cfg(cfg_), - logger(cfg.logger), - du_cfg_mng(cfg.cu_cp.node.gnb_id, config_helpers::get_supported_plmns(cfg.cu_cp.node.supported_tas)) + cfg(cfg_), logger(cfg.logger), du_cfg_mng(cfg.cu_cp.node.gnb_id, config_helpers::get_supported_plmns(cfg.cu_cp.ngaps)) { } diff --git a/lib/cu_cp/mobility_manager/mobility_manager_factory.cpp b/lib/cu_cp/mobility_manager/mobility_manager_factory.cpp index 043bfdef9c..303b477c25 100644 --- a/lib/cu_cp/mobility_manager/mobility_manager_factory.cpp +++ b/lib/cu_cp/mobility_manager/mobility_manager_factory.cpp @@ -18,10 +18,10 @@ using namespace srs_cu_cp; std::unique_ptr srsran::srs_cu_cp::create_mobility_manager(const mobility_manager_cfg& cfg, mobility_manager_cu_cp_notifier& cu_cp_notifier, - ngap_control_message_handler& ngap_handler, + ngap_repository& ngap_db, du_processor_repository& du_db, ue_manager& ue_mng) { - auto mobility_mng = std::make_unique(cfg, cu_cp_notifier, ngap_handler, du_db, ue_mng); + auto mobility_mng = std::make_unique(cfg, cu_cp_notifier, ngap_db, du_db, ue_mng); return mobility_mng; } diff --git a/lib/cu_cp/mobility_manager/mobility_manager_factory.h b/lib/cu_cp/mobility_manager/mobility_manager_factory.h index 74a494c51b..7520cd8cb6 100644 --- a/lib/cu_cp/mobility_manager/mobility_manager_factory.h +++ b/lib/cu_cp/mobility_manager/mobility_manager_factory.h @@ -19,7 +19,7 @@ namespace srs_cu_cp { /// Creates an instance of a mobility manager. std::unique_ptr create_mobility_manager(const mobility_manager_cfg& cfg, mobility_manager_cu_cp_notifier& cu_cp_notifier, - ngap_control_message_handler& ngap_handler, + ngap_repository& ngap_db, du_processor_repository& du_db, ue_manager& ue_mng); diff --git a/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp b/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp index 9bec63f256..5d11321fd0 100644 --- a/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp +++ b/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp @@ -17,12 +17,12 @@ using namespace srs_cu_cp; mobility_manager::mobility_manager(const mobility_manager_cfg& cfg_, mobility_manager_cu_cp_notifier& cu_cp_notifier_, - ngap_control_message_handler& ngap_handler_, + ngap_repository& ngap_db_, du_processor_repository& du_db_, ue_manager& ue_mng_) : cfg(cfg_), cu_cp_notifier(cu_cp_notifier_), - ngap_handler(ngap_handler_), + ngap_db(ngap_db_), du_db(du_db_), ue_mng(ue_mng_), logger(srslog::fetch_basic_logger("CU-CP")) @@ -163,12 +163,20 @@ void mobility_manager::handle_inter_cu_handover(ue_index_t source_ue_index request.pdu_sessions.insert({pdu_session.first, qos_flows}); } + cu_cp_ue_context& ue_ctxt = u->get_ue_context(); + + auto* ngap = ngap_db.find_ngap(ue_ctxt.plmn); + if (ngap == nullptr) { + logger.error("ue={}: Couldn't find NGAP", source_ue_index); + return; + } + // Send handover preparation request to the NGAP handler. - auto ho_trigger = - [this, request, response = ngap_handover_preparation_response{}](coro_context>& ctx) mutable { - CORO_BEGIN(ctx); - CORO_AWAIT_VALUE(response, ngap_handler.handle_handover_preparation_request(request)); - CORO_RETURN(); - }; + auto ho_trigger = [ngap, request, response = ngap_handover_preparation_response{}]( + coro_context>& ctx) mutable { + CORO_BEGIN(ctx); + CORO_AWAIT_VALUE(response, ngap->get_ngap_control_message_handler().handle_handover_preparation_request(request)); + CORO_RETURN(); + }; u->get_task_sched().schedule_async_task(launch_async(std::move(ho_trigger))); } diff --git a/lib/cu_cp/mobility_manager/mobility_manager_impl.h b/lib/cu_cp/mobility_manager/mobility_manager_impl.h index 3d6bc4a4f6..70c2af6500 100644 --- a/lib/cu_cp/mobility_manager/mobility_manager_impl.h +++ b/lib/cu_cp/mobility_manager/mobility_manager_impl.h @@ -10,6 +10,7 @@ #pragma once +#include "../ngap_repository.h" #include "../ue_manager/ue_manager_impl.h" #include "srsran/cu_cp/cu_cp_command_handler.h" #include "srsran/cu_cp/cu_cp_f1c_handler.h" @@ -53,7 +54,7 @@ class mobility_manager final : public mobility_manager_measurement_handler, publ public: mobility_manager(const mobility_manager_cfg& cfg, mobility_manager_cu_cp_notifier& cu_cp_notifier_, - ngap_control_message_handler& ngap_handler_, + ngap_repository& ngap_db_, du_processor_repository& du_db_, ue_manager& ue_mng_); @@ -76,7 +77,7 @@ class mobility_manager final : public mobility_manager_measurement_handler, publ mobility_manager_cfg cfg; mobility_manager_cu_cp_notifier& cu_cp_notifier; - ngap_control_message_handler& ngap_handler; + ngap_repository& ngap_db; du_processor_repository& du_db; ue_manager& ue_mng; diff --git a/lib/cu_cp/routines/amf_connection_removal_routine.cpp b/lib/cu_cp/routines/amf_connection_removal_routine.cpp new file mode 100644 index 0000000000..50b3551821 --- /dev/null +++ b/lib/cu_cp/routines/amf_connection_removal_routine.cpp @@ -0,0 +1,40 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "amf_connection_removal_routine.h" +#include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/support/async/coroutine.h" + +using namespace srsran; +using namespace srs_cu_cp; + +amf_connection_removal_routine::amf_connection_removal_routine(ngap_interface* ngap_, + std::atomic& amf_connected_) : + ngap(ngap_), amf_connected(amf_connected_), logger(srslog::fetch_basic_logger("CU-CP")) +{ +} + +void amf_connection_removal_routine::operator()(coro_context>& ctx) +{ + CORO_BEGIN(ctx); + + if (ngap == nullptr) { + logger.error("AMF connection removal routine called with null NGAP interface"); + CORO_EARLY_RETURN(); + } + + // Launch procedure to remove AMF connection. + CORO_AWAIT(ngap->handle_amf_disconnection_request()); + + // Update AMF connection handler state. + amf_connected = false; + + CORO_RETURN(); +} diff --git a/lib/cu_cp/routines/amf_connection_removal_routine.h b/lib/cu_cp/routines/amf_connection_removal_routine.h new file mode 100644 index 0000000000..30e16da076 --- /dev/null +++ b/lib/cu_cp/routines/amf_connection_removal_routine.h @@ -0,0 +1,35 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "../ngap_repository.h" +#include "srsran/ngap/ngap.h" +#include "srsran/support/async/async_task.h" + +namespace srsran { +namespace srs_cu_cp { + +/// \brief Handles the setup of the connection between the CU-CP and AMF, handling in particular the NG Setup procedure. +class amf_connection_removal_routine +{ +public: + amf_connection_removal_routine(ngap_interface* ngap_, std::atomic& amf_connected_); + + void operator()(coro_context>& ctx); + +private: + ngap_interface* ngap = nullptr; + std::atomic& amf_connected; + srslog::basic_logger& logger; +}; + +} // namespace srs_cu_cp +} // namespace srsran diff --git a/lib/cu_cp/routines/amf_connection_setup_routine.cpp b/lib/cu_cp/routines/amf_connection_setup_routine.cpp index a5013b0e32..644bc6b083 100644 --- a/lib/cu_cp/routines/amf_connection_setup_routine.cpp +++ b/lib/cu_cp/routines/amf_connection_setup_routine.cpp @@ -9,13 +9,20 @@ */ #include "amf_connection_setup_routine.h" +#include "srsran/cu_cp/cu_cp_types.h" #include "srsran/ngap/ngap_setup.h" +#include "srsran/support/async/coroutine.h" using namespace srsran; using namespace srs_cu_cp; -amf_connection_setup_routine::amf_connection_setup_routine(ngap_connection_manager& ngap_conn_mng_) : - ngap_conn_mng(ngap_conn_mng_) +amf_connection_setup_routine::amf_connection_setup_routine(ngap_repository& ngap_db_, + std::atomic& amf_connected_) : + ngap_db(ngap_db_), + amf_connected(amf_connected_), + amf_index(ngap_db_.get_ngaps().begin()->first), + ngap(ngap_db_.get_ngaps().begin()->second), + logger(srslog::fetch_basic_logger("CU-CP")) { } @@ -23,18 +30,38 @@ void amf_connection_setup_routine::operator()(coro_context>& ct { CORO_BEGIN(ctx); - if (not ngap_conn_mng.handle_amf_tnl_connection_request()) { + if (not ngap->handle_amf_tnl_connection_request()) { CORO_EARLY_RETURN(false); } // Initiate NG Setup. - CORO_AWAIT_VALUE(result_msg, send_ng_setup_request()); + CORO_AWAIT_VALUE(result_msg, ngap->handle_ng_setup_request(/*max_setup_retries*/ 1)); - CORO_RETURN(std::holds_alternative(result_msg)); + success = std::holds_alternative(result_msg); + + // Handle result of NG setup. + handle_connection_setup_result(); + + if (success) { + // Update PLMN lookups in NGAP repository after successful NGSetup. + ngap_db.update_plmn_lookup(amf_index); + + std::string plmn_list; + for (const auto& plmn : ngap->get_ngap_context().get_supported_plmns()) { + plmn_list += plmn.to_string() + " "; + } + + logger.info("Connected to AMF. Supported PLMNs: {}", plmn_list); + } else { + logger.error("Failed to connect to AMF"); + CORO_EARLY_RETURN(false); + } + + CORO_RETURN(success); } -async_task amf_connection_setup_routine::send_ng_setup_request() +void amf_connection_setup_routine::handle_connection_setup_result() { - // Initiate NG Setup Request. - return ngap_conn_mng.handle_ng_setup_request(/*max_setup_retries*/ 1); + // Update AMF connection handler state. + amf_connected = success; } diff --git a/lib/cu_cp/routines/amf_connection_setup_routine.h b/lib/cu_cp/routines/amf_connection_setup_routine.h index f3765d8b2a..78b511ad63 100644 --- a/lib/cu_cp/routines/amf_connection_setup_routine.h +++ b/lib/cu_cp/routines/amf_connection_setup_routine.h @@ -11,6 +11,7 @@ #pragma once #include "../cu_cp_impl_interface.h" +#include "../ngap_repository.h" #include "srsran/cu_cp/cu_cp_configuration.h" #include "srsran/ngap/ngap.h" #include "srsran/support/async/async_task.h" @@ -22,16 +23,21 @@ namespace srs_cu_cp { class amf_connection_setup_routine { public: - amf_connection_setup_routine(ngap_connection_manager& ngap_conn_mng_); + amf_connection_setup_routine(ngap_repository& ngap_db_, std::atomic& amf_connected_); void operator()(coro_context>& ctx); private: - async_task send_ng_setup_request(); + void handle_connection_setup_result(); - ngap_connection_manager& ngap_conn_mng; + ngap_repository& ngap_db; + std::atomic& amf_connected; + amf_index_t amf_index = amf_index_t::invalid; + ngap_interface* ngap = nullptr; + srslog::basic_logger& logger; ngap_ng_setup_result result_msg = {}; + bool success = false; }; } // namespace srs_cu_cp diff --git a/lib/ngap/ngap_asn1_helpers.h b/lib/ngap/ngap_asn1_helpers.h index f7d4907ed0..07d16dfe15 100644 --- a/lib/ngap/ngap_asn1_helpers.h +++ b/lib/ngap/ngap_asn1_helpers.h @@ -42,7 +42,7 @@ inline void fill_asn1_ng_setup_request(asn1::ngap::ng_setup_request_s& asn1_requ global_gnb.gnb_id.set_gnb_id(); global_gnb.gnb_id.gnb_id().from_number(ngap_ctxt.gnb_id.id, ngap_ctxt.gnb_id.bit_length); // TODO: Which PLMN do we need to use here? - global_gnb.plmn_id = ngap_ctxt.supported_tas.front().plmn.to_bytes(); + global_gnb.plmn_id = ngap_ctxt.supported_tas.front().plmn_list.front().plmn_id.to_bytes(); // fill ran node name asn1_request->ran_node_name_present = true; @@ -56,21 +56,22 @@ inline void fill_asn1_ng_setup_request(asn1::ngap::ng_setup_request_s& asn1_requ asn1_supported_ta_item.tac.from_number(supported_ta_item.tac); // fill broadcast plmn list - // TODO: add support for multiple plmn per ta - asn1::ngap::broadcast_plmn_item_s asn1_broadcast_plmn_item = {}; + for (const auto& plmn_item : supported_ta_item.plmn_list) { + asn1::ngap::broadcast_plmn_item_s asn1_broadcast_plmn_item = {}; - // fill plmn id - asn1_broadcast_plmn_item.plmn_id = supported_ta_item.plmn.to_bytes(); + // fill plmn id + asn1_broadcast_plmn_item.plmn_id = plmn_item.plmn_id.to_bytes(); - // fill tai slice support list - for (const auto& slice_support_item : supported_ta_item.supported_slices) { - // fill s_nssai - asn1::ngap::slice_support_item_s asn1_slice_support_item = {}; - asn1_slice_support_item.s_nssai = s_nssai_to_asn1(slice_support_item); + // fill tai slice support list + for (const auto& slice_support_item : plmn_item.slice_support_list) { + // fill s_nssai + asn1::ngap::slice_support_item_s asn1_slice_support_item = {}; + asn1_slice_support_item.s_nssai = s_nssai_to_asn1(slice_support_item); - asn1_broadcast_plmn_item.tai_slice_support_list.push_back(asn1_slice_support_item); + asn1_broadcast_plmn_item.tai_slice_support_list.push_back(asn1_slice_support_item); + } + asn1_supported_ta_item.broadcast_plmn_list.push_back(asn1_broadcast_plmn_item); } - asn1_supported_ta_item.broadcast_plmn_list.push_back(asn1_broadcast_plmn_item); asn1_request->supported_ta_list.push_back(asn1_supported_ta_item); } diff --git a/lib/rrc/ue/procedures/rrc_setup_procedure.cpp b/lib/rrc/ue/procedures/rrc_setup_procedure.cpp index 17dde14f83..8063a1e20f 100644 --- a/lib/rrc/ue/procedures/rrc_setup_procedure.cpp +++ b/lib/rrc/ue/procedures/rrc_setup_procedure.cpp @@ -101,6 +101,7 @@ void rrc_setup_procedure::send_initial_ue_msg(const asn1::rrc_nr::rrc_setup_comp const auto& rrc_setup_complete = rrc_setup_complete_msg.crit_exts.rrc_setup_complete(); init_ue_msg.ue_index = context.ue_index; + init_ue_msg.plmn = context.cell.cgi.plmn_id; init_ue_msg.nas_pdu = rrc_setup_complete.ded_nas_msg.copy(); init_ue_msg.establishment_cause = static_cast(context.connection_cause.value); init_ue_msg.user_location_info.nr_cgi = context.cell.cgi; diff --git a/lib/rrc/ue/rrc_ue_message_handlers.cpp b/lib/rrc/ue/rrc_ue_message_handlers.cpp index b31ea8608c..4c01e9205d 100644 --- a/lib/rrc/ue/rrc_ue_message_handlers.cpp +++ b/lib/rrc/ue/rrc_ue_message_handlers.cpp @@ -59,7 +59,7 @@ void rrc_ue_impl::handle_ul_ccch_pdu(byte_buffer pdu) void rrc_ue_impl::handle_rrc_setup_request(const asn1::rrc_nr::rrc_setup_request_s& request_msg) { // Perform various checks to make sure we can serve the RRC Setup Request - if (not cu_cp_notifier.on_ue_setup_request()) { + if (not cu_cp_notifier.on_ue_setup_request(context.cell.cgi.plmn_id)) { logger.log_error("Sending Connection Reject. Cause: RRC connections not allowed"); on_ue_release_required(ngap_cause_radio_network_t::unspecified); return; @@ -218,6 +218,7 @@ void rrc_ue_impl::handle_ul_info_transfer(const ul_info_transfer_ies_s& ul_info_ { cu_cp_ul_nas_transport ul_nas_msg = {}; ul_nas_msg.ue_index = context.ue_index; + ul_nas_msg.plmn = context.cell.cgi.plmn_id; ul_nas_msg.nas_pdu = ul_info_transfer.ded_nas_msg.copy(); ul_nas_msg.user_location_info.nr_cgi = context.cell.cgi; ul_nas_msg.user_location_info.tai.plmn_id = context.cell.cgi.plmn_id; diff --git a/tests/integrationtests/du_high_cu/cu_du_test.cpp b/tests/integrationtests/du_high_cu/cu_du_test.cpp index f04fc91876..5279307f35 100644 --- a/tests/integrationtests/du_high_cu/cu_du_test.cpp +++ b/tests/integrationtests/du_high_cu/cu_du_test.cpp @@ -51,8 +51,9 @@ class cu_du_test : public ::testing::Test // create CU-CP config srs_cu_cp::cu_cp_configuration cu_cfg = config_helpers::make_default_cu_cp_config(); cu_cfg.services.cu_cp_executor = &workers.ctrl_exec; - cu_cfg.services.n2_gw = &*amf; cu_cfg.services.timers = &timers; + cu_cfg.ngaps.push_back( + srs_cu_cp::cu_cp_configuration::ngap_params{&*amf, {{7, {{plmn_identity::test_value(), {{1}}}}}}}); // create CU-CP. cu_cp_obj = create_cu_cp(cu_cfg); diff --git a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp index 5d8e8d39f9..55cc7c406c 100644 --- a/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp +++ b/tests/integrationtests/du_high_cu/du_high_cu_test_simulator.cpp @@ -94,8 +94,9 @@ du_high_cu_test_simulator::du_high_cu_test_simulator(const du_high_cu_cp_test_si // Prepare CU-CP config. srs_cu_cp::cu_cp_configuration cu_cfg = config_helpers::make_default_cu_cp_config(); cu_cfg.services.cu_cp_executor = workers.executors["CU-CP"]; - cu_cfg.services.n2_gw = &n2_gw; cu_cfg.services.timers = &timers; + cu_cfg.ngaps.push_back( + srs_cu_cp::cu_cp_configuration::ngap_params{&n2_gw, {{7, {{plmn_identity::test_value(), {{1}}}}}}}); // Instatiate CU-CP. cu_cp_inst = create_cu_cp(cu_cfg); @@ -104,7 +105,9 @@ du_high_cu_test_simulator::du_high_cu_test_simulator(const du_high_cu_cp_test_si cu_cp_inst->start(); // Connect AMF by injecting a ng_setup_response - cu_cp_inst->get_ng_handler().get_ngap_message_handler().handle_message(srs_cu_cp::generate_ng_setup_response()); + cu_cp_inst->get_ng_handler() + .get_ngap_message_handler(plmn_identity::test_value()) + ->handle_message(srs_cu_cp::generate_ng_setup_response()); // Connect F1-C to CU-CP. f1c_gw.attach_cu_cp_du_repo(cu_cp_inst->get_f1c_handler()); diff --git a/tests/integrationtests/ngap/ngap_integration_test.cpp b/tests/integrationtests/ngap/ngap_integration_test.cpp index 215cd65688..0ddcfcfd64 100644 --- a/tests/integrationtests/ngap/ngap_integration_test.cpp +++ b/tests/integrationtests/ngap/ngap_integration_test.cpp @@ -108,15 +108,27 @@ class ngap_integration_test : public ::testing::Test protected: ngap_integration_test() : cu_cp_cfg([this]() { + sctp_network_connector_config nw_config; + nw_config.dest_name = "AMF"; + nw_config.if_name = "N2"; + nw_config.connect_address = "10.12.1.105"; + nw_config.connect_port = 38412; + nw_config.bind_address = "10.8.1.10"; + nw_config.bind_port = 0; + nw_config.non_blocking_mode = true; + adapter = std::make_unique(nw_config); + cu_cp_configuration cucfg = config_helpers::make_default_cu_cp_config(); cucfg.services.timers = &timers; cucfg.services.cu_cp_executor = &ctrl_worker; + cucfg.ngaps.push_back( + cu_cp_configuration::ngap_params{adapter.get(), {{7, {{plmn_identity::test_value(), {{1}}}}}}}); return cucfg; }()) { cfg.gnb_id = cu_cp_cfg.node.gnb_id; cfg.ran_node_name = cu_cp_cfg.node.ran_node_name; - cfg.supported_tas = cu_cp_cfg.node.supported_tas; + cfg.supported_tas = cu_cp_cfg.ngaps.front().supported_tas; cfg.pdu_session_setup_timeout = cu_cp_cfg.ue.pdu_session_setup_timeout; } @@ -125,17 +137,7 @@ class ngap_integration_test : public ::testing::Test srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - sctp_network_connector_config nw_config; - nw_config.dest_name = "AMF"; - nw_config.if_name = "N2"; - nw_config.connect_address = "10.12.1.105"; - nw_config.connect_port = 38412; - nw_config.bind_address = "10.8.1.10"; - nw_config.bind_port = 0; - nw_config.non_blocking_mode = true; - adapter = std::make_unique(nw_config); - - ngap = create_ngap(cfg, cu_cp_notifier, *adapter, timers, ctrl_worker); + ngap = create_ngap(cfg, cu_cp_notifier, *cu_cp_cfg.ngaps.front().n2_gw, timers, ctrl_worker); } timer_manager timers; diff --git a/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp b/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp index aed483e637..1427b4ee40 100644 --- a/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp @@ -42,7 +42,7 @@ TEST_F(cu_cp_connectivity_test, when_cu_cp_is_created_then_it_is_not_connected_t ASSERT_FALSE(get_amf().try_pop_rx_pdu(ngap_pdu)) << "The CU-CP should not send a message to the NG interface before being started"; - ASSERT_FALSE(get_cu_cp().get_ng_handler().amf_is_connected()); + ASSERT_FALSE(get_cu_cp().get_ng_handler().amfs_are_connected()); } TEST_F(cu_cp_connectivity_test, when_cu_cp_starts_then_it_initiates_ng_setup_procedure_and_blocks_waiting_for_response) @@ -59,7 +59,7 @@ TEST_F(cu_cp_connectivity_test, when_cu_cp_starts_then_it_initiates_ng_setup_pro ASSERT_TRUE(is_pdu_type(ngap_pdu, asn1::ngap::ngap_elem_procs_o::init_msg_c::types::ng_setup_request)) << "CU-CP did not setup the AMF connection"; - ASSERT_TRUE(get_cu_cp().get_ng_handler().amf_is_connected()); + ASSERT_TRUE(get_cu_cp().get_ng_handler().amfs_are_connected()); } TEST_F(cu_cp_connectivity_test, when_ng_setup_fails_then_cu_cp_is_not_in_amf_connected_state) @@ -76,7 +76,7 @@ TEST_F(cu_cp_connectivity_test, when_ng_setup_fails_then_cu_cp_is_not_in_amf_con ASSERT_TRUE(is_pdu_type(ngap_pdu, asn1::ngap::ngap_elem_procs_o::init_msg_c::types::ng_setup_request)) << "CU-CP did not setup the AMF connection"; - ASSERT_FALSE(get_cu_cp().get_ng_handler().amf_is_connected()); + ASSERT_FALSE(get_cu_cp().get_ng_handler().amfs_are_connected()); } //----------------------------------------------------------------------------------// diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.cpp b/tests/unittests/cu_cp/cu_cp_test_environment.cpp index ba0e051f74..10a678677e 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.cpp +++ b/tests/unittests/cu_cp/cu_cp_test_environment.cpp @@ -31,6 +31,7 @@ #include "srsran/f1ap/common/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include "srsran/ran/cu_types.h" +#include "srsran/ran/plmn_identity.h" #include "srsran/security/integrity.h" #include "srsran/support/executors/task_worker.h" @@ -56,7 +57,7 @@ cu_cp_test_environment::cu_cp_test_environment(cu_cp_test_env_params params_) : params(std::move(params_)), cu_cp_workers(std::make_unique()), timers(64), - amf_stub(std::move(params.amf_stub)) + amf_configs(std::move(params.amf_configs)) { // Initialize logging test_logger.set_level(srslog::basic_levels::debug); @@ -70,12 +71,15 @@ cu_cp_test_environment::cu_cp_test_environment(cu_cp_test_env_params params_) : // Create CU-CP config cu_cp_cfg = config_helpers::make_default_cu_cp_config(); cu_cp_cfg.services.cu_cp_executor = cu_cp_workers->exec.get(); - cu_cp_cfg.services.n2_gw = &*amf_stub; cu_cp_cfg.services.timers = &timers; cu_cp_cfg.admission.max_nof_dus = params.max_nof_dus; cu_cp_cfg.admission.max_nof_cu_ups = params.max_nof_cu_ups; cu_cp_cfg.admission.max_nof_ues = params.max_nof_ues; cu_cp_cfg.bearers.drb_config = config_helpers::make_default_cu_cp_qos_config_list(); + // > NGAP config + for (const auto& [amf_index, amf_config] : amf_configs) { + cu_cp_cfg.ngaps.push_back(cu_cp_configuration::ngap_params{&*amf_config.amf_stub, amf_config.supported_tas}); + } // > Security config. cu_cp_cfg.security.int_algo_pref_list = {security::integrity_algorithm::nia2, security::integrity_algorithm::nia1, @@ -242,9 +246,11 @@ bool cu_cp_test_environment::tick_until(std::chrono::milliseconds timeout, const return stop_condition(); } -bool cu_cp_test_environment::wait_for_ngap_tx_pdu(ngap_message& pdu, std::chrono::milliseconds timeout) +bool cu_cp_test_environment::wait_for_ngap_tx_pdu(ngap_message& pdu, + std::chrono::milliseconds timeout, + unsigned amf_idx) { - return tick_until(timeout, [&]() { return amf_stub->try_pop_rx_pdu(pdu); }); + return tick_until(timeout, [&]() { return amf_configs.at(amf_idx).amf_stub->try_pop_rx_pdu(pdu); }); } bool cu_cp_test_environment::wait_for_e1ap_tx_pdu(unsigned cu_up_idx, @@ -278,14 +284,19 @@ const cu_cp_test_environment::ue_context* cu_cp_test_environment::find_ue_contex void cu_cp_test_environment::run_ng_setup() { - ngap_message ng_setup_resp = srs_cu_cp::generate_ng_setup_response(); - get_amf().enqueue_next_tx_pdu(ng_setup_resp); + for (const auto& [amf_index, amf_config] : amf_configs) { + get_amf(amf_index).enqueue_next_tx_pdu(srs_cu_cp::generate_ng_setup_response()); + } report_fatal_error_if_not(get_cu_cp().start(), "Failed to start CU-CP"); ngap_message ngap_pdu; - report_fatal_error_if_not(get_amf().try_pop_rx_pdu(ngap_pdu), "CU-CP did not send the NG Setup Request to the AMF"); - report_fatal_error_if_not(is_pdu_type(ngap_pdu, asn1::ngap::ngap_elem_procs_o::init_msg_c::types::ng_setup_request), - "CU-CP did not setup the AMF connection"); + for (const auto& [amf_index, amf_config] : amf_configs) { + report_fatal_error_if_not(get_amf(amf_index).try_pop_rx_pdu(ngap_pdu), + "CU-CP did not send the NG Setup Request to the AMF {}", + amf_index); + report_fatal_error_if_not(is_pdu_type(ngap_pdu, asn1::ngap::ngap_elem_procs_o::init_msg_c::types::ng_setup_request), + "CU-CP did not setup the AMF connection"); + } } std::optional cu_cp_test_environment::connect_new_du() diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.h b/tests/unittests/cu_cp/cu_cp_test_environment.h index 25554a78b0..593da8e3e7 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.h +++ b/tests/unittests/cu_cp/cu_cp_test_environment.h @@ -10,23 +10,44 @@ #pragma once +#include "../e1ap/common/e1ap_cu_cp_test_messages.h" #include "test_doubles/mock_amf.h" #include "test_doubles/mock_cu_up.h" #include "test_doubles/mock_du.h" -#include "tests/unittests/e1ap/common/e1ap_cu_cp_test_messages.h" #include "srsran/cu_cp/cu_cp.h" #include "srsran/cu_cp/cu_cp_configuration.h" +#include "srsran/cu_cp/cu_cp_types.h" +#include "srsran/ran/plmn_identity.h" +#include #include namespace srsran { namespace srs_cu_cp { -struct cu_cp_test_env_params { - unsigned max_nof_cu_ups = 4; - unsigned max_nof_dus = 4; - unsigned max_nof_ues = 8192; +struct cu_cp_test_amf_config { + std::vector supported_tas; /// Injected AMF stub to handle CU-CP PDUs. - std::unique_ptr amf_stub = create_mock_amf(); + std::unique_ptr amf_stub; +}; + +struct cu_cp_test_env_params { + cu_cp_test_env_params(unsigned max_nof_cu_ups_ = 8, + unsigned max_nof_dus_ = 8, + unsigned max_nof_ues_ = 8192, + const std::vector>& amf_config_ = + {{supported_tracking_area{7, {{plmn_identity::test_value(), {{1}}}}}}}) : + max_nof_cu_ups(max_nof_cu_ups_), max_nof_dus(max_nof_dus_), max_nof_ues(max_nof_ues_) + { + uint16_t amf_idx = 0; + for (const auto& supported_tas : amf_config_) { + amf_configs.emplace(amf_idx, cu_cp_test_amf_config{supported_tas, create_mock_amf()}); + amf_idx++; + } + } + unsigned max_nof_cu_ups; + unsigned max_nof_dus; + unsigned max_nof_ues; + std::map amf_configs; }; class cu_cp_test_environment @@ -49,7 +70,7 @@ class cu_cp_test_environment srslog::basic_logger& cu_cp_logger = srslog::fetch_basic_logger("CU-CP"); cu_cp& get_cu_cp() { return *cu_cp_inst; } - mock_amf& get_amf() { return *amf_stub; } + mock_amf& get_amf(size_t amf_index = 0) { return *amf_configs.at(amf_index).amf_stub; } mock_du& get_du(size_t du_index) { return *dus.at(du_index); } mock_cu_up& get_cu_up(size_t cu_up_index) { return *cu_ups.at(cu_up_index); } @@ -123,7 +144,9 @@ class cu_cp_test_environment bool tick_until(std::chrono::milliseconds timeout, const std::function& stop_condition); /// Tick CU-CP timer until a NGAP PDU is sent. - bool wait_for_ngap_tx_pdu(ngap_message& ngap_pdu, std::chrono::milliseconds timeout = std::chrono::milliseconds{500}); + bool wait_for_ngap_tx_pdu(ngap_message& ngap_pdu, + std::chrono::milliseconds timeout = std::chrono::milliseconds{500}, + unsigned amf_idx = 0); bool wait_for_e1ap_tx_pdu(unsigned cu_up_idx, e1ap_message& e1ap_pdu, @@ -202,7 +225,7 @@ class cu_cp_test_environment timer_manager timers; /// Notifiers for the CU-CP interface. - std::unique_ptr amf_stub; + std::map amf_configs; // emulated CU-UP nodes. std::unordered_map> cu_ups; diff --git a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp index 5032455f8c..cf3a50d45d 100644 --- a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp +++ b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp @@ -14,6 +14,7 @@ #include "tests/unittests/cu_cp/test_helpers.h" #include "tests/unittests/f1ap/cu_cp/f1ap_cu_test_helpers.h" #include "srsran/cu_cp/cu_cp_configuration_helpers.h" +#include "srsran/ran/plmn_identity.h" #include using namespace srsran; @@ -31,7 +32,7 @@ class dummy_task_sched final : public common_task_scheduler }; struct dummy_cu_cp_ue_admission_controller : public cu_cp_ue_admission_controller { - bool request_ue_setup() const override { return true; } + bool request_ue_setup(plmn_identity plmn) const override { return true; } }; struct dummy_cu_cp_measurement_handler : public cu_cp_measurement_handler { @@ -105,11 +106,13 @@ du_processor_test::du_processor_test() : cu_cp_configuration cucfg = config_helpers::make_default_cu_cp_config(); cucfg.services.timers = &timers; cucfg.services.cu_cp_executor = &ctrl_worker; + cu_cp_cfg.ngaps.push_back(cu_cp_configuration::ngap_params{nullptr, {{7, {{plmn_identity::test_value(), {{1}}}}}}}); + return cucfg; }()), common_task_sched(std::make_unique()), - du_cfg_mgr{cu_cp_cfg.node.gnb_id, config_helpers::get_supported_plmns(cu_cp_cfg.node.supported_tas)} + du_cfg_mgr{cu_cp_cfg.node.gnb_id, config_helpers::get_supported_plmns(cu_cp_cfg.ngaps)} { test_logger.set_level(srslog::basic_levels::debug); cu_cp_logger.set_level(srslog::basic_levels::debug); diff --git a/tests/unittests/f1ap/common/f1ap_cu_test_messages.h b/tests/unittests/f1ap/common/f1ap_cu_test_messages.h index 7cc8fdda76..0a5c2742f6 100644 --- a/tests/unittests/f1ap/common/f1ap_cu_test_messages.h +++ b/tests/unittests/f1ap/common/f1ap_cu_test_messages.h @@ -10,7 +10,7 @@ #pragma once -#include "tests/test_doubles/f1ap/f1ap_test_messages.h" +#include "../../../test_doubles/f1ap/f1ap_test_messages.h" #include "srsran/asn1/f1ap/f1ap_ies.h" #include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" diff --git a/tests/unittests/ngap/ngap_asn1_packer_test.cpp b/tests/unittests/ngap/ngap_asn1_packer_test.cpp index a16b6bba8c..ce7f5e9e94 100644 --- a/tests/unittests/ngap/ngap_asn1_packer_test.cpp +++ b/tests/unittests/ngap/ngap_asn1_packer_test.cpp @@ -65,7 +65,7 @@ class ngap_asn1_packer_test : public ::testing::Test TEST_F(ngap_asn1_packer_test, when_packing_successful_then_pdu_matches_tv) { // Populate message - ngap_context_t ngap_ctxt = {{411, 22}, "srsgnb01", {{7, plmn_identity::test_value(), {{1}}}}, {}, 256}; + ngap_context_t ngap_ctxt = {{411, 22}, "srsgnb01", {{7, {{plmn_identity::test_value(), {{1}}}}}}, {}, 256}; ngap_message ngap_msg = {}; ngap_msg.pdu.set_init_msg(); diff --git a/tests/unittests/ngap/ngap_test_helpers.cpp b/tests/unittests/ngap/ngap_test_helpers.cpp index d109bf3f0d..a411c7b047 100644 --- a/tests/unittests/ngap/ngap_test_helpers.cpp +++ b/tests/unittests/ngap/ngap_test_helpers.cpp @@ -14,6 +14,7 @@ #include "srsran/cu_cp/cu_cp_configuration_helpers.h" #include "srsran/ran/cu_types.h" #include "srsran/ran/lcid.h" +#include "srsran/ran/plmn_identity.h" #include "srsran/support/async/async_test_utils.h" #include "srsran/support/test_utils.h" #include @@ -26,6 +27,7 @@ ngap_test::ngap_test() : cu_cp_configuration cucfg = config_helpers::make_default_cu_cp_config(); cucfg.services.timers = &timers; cucfg.services.cu_cp_executor = &ctrl_worker; + cucfg.ngaps.push_back(cu_cp_configuration::ngap_params{&n2_gw, {{7, {{plmn_identity::test_value(), {{1}}}}}}}); return cucfg; }()) { @@ -36,9 +38,9 @@ ngap_test::ngap_test() : ngap_configuration ngap_cfg{}; ngap_cfg.gnb_id = cu_cp_cfg.node.gnb_id; ngap_cfg.ran_node_name = cu_cp_cfg.node.ran_node_name; - ngap_cfg.supported_tas = cu_cp_cfg.node.supported_tas; + ngap_cfg.supported_tas = cu_cp_cfg.ngaps.front().supported_tas; ngap_cfg.pdu_session_setup_timeout = cu_cp_cfg.ue.pdu_session_setup_timeout; - ngap = create_ngap(ngap_cfg, cu_cp_notifier, n2_gw, timers, ctrl_worker); + ngap = create_ngap(ngap_cfg, cu_cp_notifier, *cu_cp_cfg.ngaps.front().n2_gw, timers, ctrl_worker); cu_cp_notifier.connect_ngap(ngap->get_ngap_ue_context_removal_handler()); diff --git a/tests/unittests/ngap/ngap_test_messages.cpp b/tests/unittests/ngap/ngap_test_messages.cpp index fdfea7eab3..9b44cdbeb5 100644 --- a/tests/unittests/ngap/ngap_test_messages.cpp +++ b/tests/unittests/ngap/ngap_test_messages.cpp @@ -17,6 +17,7 @@ #include "srsran/ngap/ngap_message.h" #include "srsran/ngap/ngap_types.h" #include "srsran/ran/cu_types.h" +#include "srsran/ran/plmn_identity.h" #include using namespace srsran; @@ -59,7 +60,7 @@ bool srsran::srs_cu_cp::is_pdu_type(const ngap_message& return pdu.pdu.successful_outcome().value.type().value == type; } -ngap_message srsran::srs_cu_cp::generate_ng_setup_response() +ngap_message srsran::srs_cu_cp::generate_ng_setup_response(plmn_identity plmn) { ngap_message ng_setup_response = {}; @@ -70,7 +71,7 @@ ngap_message srsran::srs_cu_cp::generate_ng_setup_response() setup_res->amf_name.from_string("open5gs-amf0"); served_guami_item_s served_guami_item; - served_guami_item.guami.plmn_id.from_string("00f110"); + served_guami_item.guami.plmn_id = plmn.to_bytes(); served_guami_item.guami.amf_region_id.from_number(2); served_guami_item.guami.amf_set_id.from_number(1); served_guami_item.guami.amf_pointer.from_number(0); @@ -79,7 +80,7 @@ ngap_message srsran::srs_cu_cp::generate_ng_setup_response() setup_res->relative_amf_capacity = 255; plmn_support_item_s plmn_support_item = {}; - plmn_support_item.plmn_id.from_string("00f110"); + plmn_support_item.plmn_id = plmn.to_bytes(); slice_support_item_s slice_support_item = {}; slice_support_item.s_nssai.sst.from_number(1); diff --git a/tests/unittests/ngap/ngap_test_messages.h b/tests/unittests/ngap/ngap_test_messages.h index bb8d062611..c06dd7e13b 100644 --- a/tests/unittests/ngap/ngap_test_messages.h +++ b/tests/unittests/ngap/ngap_test_messages.h @@ -85,7 +85,7 @@ static const uint8_t ng_setup_request_packed[] = { 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x15, 0x40, 0x01, 0x60}; /// \brief Generate a dummy NG Setup Response. -ngap_message generate_ng_setup_response(); +ngap_message generate_ng_setup_response(plmn_identity plmn = plmn_identity::test_value()); /// \brief Generate a dummy NG Setup Failure. ngap_message generate_ng_setup_failure(); diff --git a/tests/unittests/rrc/test_helpers.h b/tests/unittests/rrc/test_helpers.h index ccde13aa39..d1d29862b2 100644 --- a/tests/unittests/rrc/test_helpers.h +++ b/tests/unittests/rrc/test_helpers.h @@ -69,7 +69,7 @@ class dummy_rrc_ue_cu_cp_adapter : public rrc_ue_context_update_notifier, public bool next_ue_setup_response = true; - bool on_ue_setup_request() override { return next_ue_setup_response; } + bool on_ue_setup_request(plmn_identity plmn) override { return next_ue_setup_response; } rrc_ue_reestablishment_context_response on_rrc_reestablishment_request(pci_t old_pci, rnti_t old_c_rnti) override { From c53180e3f1ac3a3aa60acebd373517801e5e39a2 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 3 Sep 2024 11:20:42 +0200 Subject: [PATCH 029/174] cu_cp,rrc: simplify rrc to ngap adapter --- include/srsran/rrc/rrc_du_factory.h | 3 +-- include/srsran/rrc/rrc_ue.h | 23 +++++++------------ lib/cu_cp/adapters/rrc_ue_adapters.h | 2 +- lib/cu_cp/cu_cp_impl.cpp | 1 - .../du_processor/du_processor_factory.cpp | 6 ++--- lib/cu_cp/du_processor/du_processor_factory.h | 3 +-- lib/cu_cp/du_processor/du_processor_impl.cpp | 8 +++---- lib/cu_cp/du_processor/du_processor_impl.h | 5 ++-- .../du_processor/du_processor_repository.cpp | 3 +-- .../du_processor/du_processor_repository.h | 3 +-- lib/rrc/rrc_du_factory.cpp | 2 +- lib/rrc/rrc_du_impl.cpp | 9 +++----- lib/rrc/rrc_du_impl.h | 6 ++--- .../rrc_reestablishment_procedure.cpp | 6 ++--- .../rrc_reestablishment_procedure.h | 4 ++-- lib/rrc/ue/procedures/rrc_setup_procedure.cpp | 6 ++--- lib/rrc/ue/procedures/rrc_setup_procedure.h | 10 ++++---- lib/rrc/ue/rrc_ue_impl.cpp | 10 ++++---- lib/rrc/ue/rrc_ue_impl.h | 8 +++---- lib/rrc/ue/rrc_ue_message_handlers.cpp | 9 ++++---- .../du_processor_test_helpers.cpp | 1 - tests/unittests/rrc/rrc_ue_test_helpers.h | 1 - tests/unittests/rrc/test_helpers.h | 2 +- 23 files changed, 51 insertions(+), 80 deletions(-) diff --git a/include/srsran/rrc/rrc_du_factory.h b/include/srsran/rrc/rrc_du_factory.h index eaa62e9233..6b254f6afa 100644 --- a/include/srsran/rrc/rrc_du_factory.h +++ b/include/srsran/rrc/rrc_du_factory.h @@ -22,8 +22,7 @@ struct ue_context; struct rrc_du_creation_message { const rrc_cfg_t& cfg; - rrc_ue_nas_notifier& nas_notifier; - rrc_ue_control_notifier& ngap_ctrl_notifier; + rrc_ue_ngap_notifier& ngap_notifier; rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier; }; diff --git a/include/srsran/rrc/rrc_ue.h b/include/srsran/rrc/rrc_ue.h index c68417bbca..faee7428b6 100644 --- a/include/srsran/rrc/rrc_ue.h +++ b/include/srsran/rrc/rrc_ue.h @@ -166,11 +166,11 @@ class rrc_ue_reestablishment_proc_notifier virtual void on_new_as_security_context() = 0; }; -/// Interface to notify about NAS messages. -class rrc_ue_nas_notifier +/// Interface to notify about NGAP messages. +class rrc_ue_ngap_notifier { public: - virtual ~rrc_ue_nas_notifier() = default; + virtual ~rrc_ue_ngap_notifier() = default; /// \brief Notify about the Initial UE Message. /// \param[in] msg The initial UE message. @@ -179,18 +179,6 @@ class rrc_ue_nas_notifier /// \brief Notify about an Uplink NAS Transport message. /// \param[in] msg The Uplink NAS Transport message. virtual void on_ul_nas_transport_message(const cu_cp_ul_nas_transport& msg) = 0; -}; - -struct rrc_reconfiguration_response_message { - ue_index_t ue_index = ue_index_t::invalid; - bool success = false; -}; - -/// Interface to notify about control messages. -class rrc_ue_control_notifier -{ -public: - virtual ~rrc_ue_control_notifier() = default; /// \brief Notify about the reception of an inter CU handove related RRC Reconfiguration Complete. virtual void on_inter_cu_ho_rrc_recfg_complete_received(const ue_index_t ue_index, @@ -198,6 +186,11 @@ class rrc_ue_control_notifier const unsigned tac) = 0; }; +struct rrc_reconfiguration_response_message { + ue_index_t ue_index = ue_index_t::invalid; + bool success = false; +}; + struct rrc_ue_security_mode_command_context { unsigned transaction_id; nr_cell_global_id_t sp_cell_id; diff --git a/lib/cu_cp/adapters/rrc_ue_adapters.h b/lib/cu_cp/adapters/rrc_ue_adapters.h index e8b79e1615..91565683b4 100644 --- a/lib/cu_cp/adapters/rrc_ue_adapters.h +++ b/lib/cu_cp/adapters/rrc_ue_adapters.h @@ -49,7 +49,7 @@ class rrc_ue_f1ap_pdu_adapter : public rrc_pdu_f1ap_notifier }; // Adapter between RRC UE and NGAP -class rrc_ue_ngap_adapter : public rrc_ue_nas_notifier, public rrc_ue_control_notifier +class rrc_ue_ngap_adapter : public rrc_ue_ngap_notifier { public: explicit rrc_ue_ngap_adapter(ngap_repository& ngap_db_) : ngap_db(ngap_db_) {} diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 65e3046405..9e89af4c2c 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -55,7 +55,6 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : get_cu_cp_ue_removal_handler(), get_cu_cp_ue_context_handler(), rrc_ue_ngap_notifier, - rrc_ue_ngap_notifier, common_task_sched, ue_mng, rrc_du_cu_cp_notifier, diff --git a/lib/cu_cp/du_processor/du_processor_factory.cpp b/lib/cu_cp/du_processor/du_processor_factory.cpp index 09827b7809..c25439207a 100644 --- a/lib/cu_cp/du_processor/du_processor_factory.cpp +++ b/lib/cu_cp/du_processor/du_processor_factory.cpp @@ -21,8 +21,7 @@ std::unique_ptr srsran::srs_cu_cp::create_du_processor(du_processor_config_t du_processor_config, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_nas_notifier& rrc_ue_nas_pdu_notifier_, - rrc_ue_control_notifier& rrc_ue_ngap_ctrl_notifier_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_) @@ -30,8 +29,7 @@ srsran::srs_cu_cp::create_du_processor(du_processor_config_t du_pr auto du_processor = std::make_unique(std::move(du_processor_config), cu_cp_notifier_, f1ap_pdu_notifier_, - rrc_ue_nas_pdu_notifier_, - rrc_ue_ngap_ctrl_notifier_, + ngap_notifier_, rrc_du_cu_cp_notifier, common_task_sched_, ue_mng_); diff --git a/lib/cu_cp/du_processor/du_processor_factory.h b/lib/cu_cp/du_processor/du_processor_factory.h index e05bb69165..d72036ba0e 100644 --- a/lib/cu_cp/du_processor/du_processor_factory.h +++ b/lib/cu_cp/du_processor/du_processor_factory.h @@ -27,8 +27,7 @@ class common_task_scheduler; std::unique_ptr create_du_processor(du_processor_config_t du_processor_config_, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_nas_notifier& rrc_ue_nas_pdu_notifier_, - rrc_ue_control_notifier& rrc_ue_ngap_ctrl_notifier_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_); diff --git a/lib/cu_cp/du_processor/du_processor_impl.cpp b/lib/cu_cp/du_processor/du_processor_impl.cpp index 316636f179..85497bd1b4 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.cpp +++ b/lib/cu_cp/du_processor/du_processor_impl.cpp @@ -76,15 +76,14 @@ class du_processor_impl::f1ap_du_processor_adapter : public f1ap_du_processor_no du_processor_impl::du_processor_impl(du_processor_config_t du_processor_config_, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_nas_notifier& rrc_ue_nas_pdu_notifier_, - rrc_ue_control_notifier& rrc_ue_ngap_ctrl_notifier, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_) : cfg(std::move(du_processor_config_)), cu_cp_notifier(cu_cp_notifier_), f1ap_pdu_notifier(f1ap_pdu_notifier_), - rrc_ue_nas_pdu_notifier(rrc_ue_nas_pdu_notifier_), + ngap_notifier(ngap_notifier_), ue_mng(ue_mng_), f1ap_ev_notifier(std::make_unique(*this, common_task_sched_)) { @@ -97,8 +96,7 @@ du_processor_impl::du_processor_impl(du_processor_config_t du_proc f1ap_ue_context_notifier.connect_f1(f1ap->get_f1ap_ue_context_manager()); // create RRC - rrc_du_creation_message du_creation_req{ - create_rrc_config(cfg.cu_cp_cfg), rrc_ue_nas_pdu_notifier, rrc_ue_ngap_ctrl_notifier, rrc_du_cu_cp_notifier}; + rrc_du_creation_message du_creation_req{create_rrc_config(cfg.cu_cp_cfg), ngap_notifier, rrc_du_cu_cp_notifier}; rrc = create_rrc_du(du_creation_req); rrc_du_adapter.connect_rrc_du(rrc->get_rrc_du_cell_manager(), rrc->get_rrc_du_ue_repository()); } diff --git a/lib/cu_cp/du_processor/du_processor_impl.h b/lib/cu_cp/du_processor/du_processor_impl.h index 59f9738179..d73594632e 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.h +++ b/lib/cu_cp/du_processor/du_processor_impl.h @@ -33,8 +33,7 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public du_processor_impl(du_processor_config_t du_processor_config_, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_nas_notifier& rrc_ue_nas_pdu_notifier_, - rrc_ue_control_notifier& rrc_ue_ngap_ctrl_notifier_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_); @@ -95,7 +94,7 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public du_processor_cu_cp_notifier& cu_cp_notifier; f1ap_message_notifier& f1ap_pdu_notifier; - rrc_ue_nas_notifier& rrc_ue_nas_pdu_notifier; + rrc_ue_ngap_notifier& ngap_notifier; ue_manager& ue_mng; du_processor_f1ap_ue_context_adapter f1ap_ue_context_notifier; diff --git a/lib/cu_cp/du_processor/du_processor_repository.cpp b/lib/cu_cp/du_processor/du_processor_repository.cpp index 43fa162a2d..adda220c6e 100644 --- a/lib/cu_cp/du_processor/du_processor_repository.cpp +++ b/lib/cu_cp/du_processor/du_processor_repository.cpp @@ -49,8 +49,7 @@ du_index_t du_processor_repository::add_du(std::unique_ptr du = create_du_processor(std::move(du_cfg), du_ctxt.du_to_cu_cp_notifier, *du_ctxt.f1ap_tx_pdu_notifier, - cfg.ue_nas_pdu_notifier, - cfg.ue_ngap_ctrl_notifier, + cfg.ngap_notifier, cfg.meas_config_notifier, cfg.common_task_sched, cfg.ue_mng); diff --git a/lib/cu_cp/du_processor/du_processor_repository.h b/lib/cu_cp/du_processor/du_processor_repository.h index 9ec59a143b..52b73cce7a 100644 --- a/lib/cu_cp/du_processor/du_processor_repository.h +++ b/lib/cu_cp/du_processor/du_processor_repository.h @@ -33,8 +33,7 @@ struct du_repository_config { cu_cp_du_event_handler& cu_cp_du_handler; cu_cp_ue_removal_handler& ue_removal_handler; cu_cp_ue_context_manipulation_handler& ue_context_handler; - rrc_ue_nas_notifier& ue_nas_pdu_notifier; - rrc_ue_control_notifier& ue_ngap_ctrl_notifier; + rrc_ue_ngap_notifier& ngap_notifier; common_task_scheduler& common_task_sched; ue_manager& ue_mng; rrc_du_measurement_config_notifier& meas_config_notifier; diff --git a/lib/rrc/rrc_du_factory.cpp b/lib/rrc/rrc_du_factory.cpp index 81f620ada4..39a810bd62 100644 --- a/lib/rrc/rrc_du_factory.cpp +++ b/lib/rrc/rrc_du_factory.cpp @@ -17,5 +17,5 @@ using namespace srs_cu_cp; std::unique_ptr srsran::srs_cu_cp::create_rrc_du(const rrc_du_creation_message& msg) { - return std::make_unique(msg.cfg, msg.nas_notifier, msg.ngap_ctrl_notifier, msg.rrc_du_cu_cp_notifier); + return std::make_unique(msg.cfg, msg.ngap_notifier, msg.rrc_du_cu_cp_notifier); } diff --git a/lib/rrc/rrc_du_impl.cpp b/lib/rrc/rrc_du_impl.cpp index bc785d8509..05dbaec7f2 100644 --- a/lib/rrc/rrc_du_impl.cpp +++ b/lib/rrc/rrc_du_impl.cpp @@ -20,12 +20,10 @@ using namespace srs_cu_cp; using namespace asn1::rrc_nr; rrc_du_impl::rrc_du_impl(const rrc_cfg_t& cfg_, - rrc_ue_nas_notifier& nas_notif_, - rrc_ue_control_notifier& ngap_ctrl_notif_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& meas_config_notifier_) : cfg(cfg_), - nas_notifier(nas_notif_), - ngap_ctrl_notifier(ngap_ctrl_notif_), + ngap_notifier(ngap_notifier_), meas_config_notifier(meas_config_notifier_), logger(srslog::fetch_basic_logger("RRC", false)) { @@ -137,8 +135,7 @@ rrc_ue_interface* rrc_du_impl::add_ue(const rrc_ue_creation_message& msg) auto res = ue_db.emplace(ue_index, std::make_unique(*msg.f1ap_pdu_notifier, - nas_notifier, - ngap_ctrl_notifier, + ngap_notifier, *msg.rrc_ue_cu_cp_notifier, *msg.measurement_notifier, *msg.cu_cp_ue_notifier, diff --git a/lib/rrc/rrc_du_impl.h b/lib/rrc/rrc_du_impl.h index 76ea42cc3f..87609749b8 100644 --- a/lib/rrc/rrc_du_impl.h +++ b/lib/rrc/rrc_du_impl.h @@ -25,8 +25,7 @@ class rrc_du_impl : public rrc_du { public: rrc_du_impl(const rrc_cfg_t& cfg_, - rrc_ue_nas_notifier& nas_notif_, - rrc_ue_control_notifier& ngap_ctrl_notif_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& meas_config_notifier_); ~rrc_du_impl() = default; @@ -60,8 +59,7 @@ class rrc_du_impl : public rrc_du // helpers const rrc_cfg_t cfg; - rrc_ue_nas_notifier& nas_notifier; // PDU notifier to the NGAP - rrc_ue_control_notifier& ngap_ctrl_notifier; // Control notifier to the NGAP + rrc_ue_ngap_notifier& ngap_notifier; // notifier to the NGAP rrc_du_measurement_config_notifier& meas_config_notifier; // notifier to the CU-CP srslog::basic_logger& logger; diff --git a/lib/rrc/ue/procedures/rrc_reestablishment_procedure.cpp b/lib/rrc/ue/procedures/rrc_reestablishment_procedure.cpp index b42f6e89c0..3f428de20f 100644 --- a/lib/rrc/ue/procedures/rrc_reestablishment_procedure.cpp +++ b/lib/rrc/ue/procedures/rrc_reestablishment_procedure.cpp @@ -27,7 +27,7 @@ rrc_reestablishment_procedure::rrc_reestablishment_procedure( rrc_ue_control_message_handler& srb_notifier_, rrc_ue_context_update_notifier& cu_cp_notifier_, rrc_ue_cu_cp_ue_notifier& cu_cp_ue_notifier_, - rrc_ue_nas_notifier& nas_notifier_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_ue_event_manager& event_mng_, rrc_ue_logger& logger_) : reestablishment_request(request_), @@ -38,7 +38,7 @@ rrc_reestablishment_procedure::rrc_reestablishment_procedure( srb_notifier(srb_notifier_), cu_cp_notifier(cu_cp_notifier_), cu_cp_ue_notifier(cu_cp_ue_notifier_), - nas_notifier(nas_notifier_), + ngap_notifier(ngap_notifier_), event_mng(event_mng_), logger(logger_) { @@ -131,7 +131,7 @@ async_task rrc_reestablishment_procedure::handle_rrc_reestablishment_fallb // Reject RRC Reestablishment Request by sending RRC Setup CORO_AWAIT(launch_async( - context, du_to_cu_container, rrc_ue_setup_notifier, srb_notifier, nas_notifier, event_mng, logger)); + context, du_to_cu_container, rrc_ue_setup_notifier, srb_notifier, ngap_notifier, event_mng, logger)); if (old_ue_reest_context.ue_index != ue_index_t::invalid and !old_ue_reest_context.old_ue_fully_attached) { // The UE exists but still has not established an SRB2 and DRB. Request the release of the old UE. diff --git a/lib/rrc/ue/procedures/rrc_reestablishment_procedure.h b/lib/rrc/ue/procedures/rrc_reestablishment_procedure.h index bc37cb15d5..7c56d9f8da 100644 --- a/lib/rrc/ue/procedures/rrc_reestablishment_procedure.h +++ b/lib/rrc/ue/procedures/rrc_reestablishment_procedure.h @@ -31,7 +31,7 @@ class rrc_reestablishment_procedure rrc_ue_control_message_handler& srb_notifier_, rrc_ue_context_update_notifier& cu_cp_notifier_, rrc_ue_cu_cp_ue_notifier& cu_cp_ue_notifier_, - rrc_ue_nas_notifier& nas_notifier_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_ue_event_manager& event_mng_, rrc_ue_logger& logger_); @@ -67,7 +67,7 @@ class rrc_reestablishment_procedure rrc_ue_control_message_handler& srb_notifier; // for creating SRBs rrc_ue_context_update_notifier& cu_cp_notifier; // notifier to the CU-CP rrc_ue_cu_cp_ue_notifier& cu_cp_ue_notifier; // notifier to the CU-CP UE - rrc_ue_nas_notifier& nas_notifier; // notifier to the NGAP + rrc_ue_ngap_notifier& ngap_notifier; // notifier to the NGAP rrc_ue_event_manager& event_mng; // event manager for the RRC UE entity rrc_ue_logger& logger; diff --git a/lib/rrc/ue/procedures/rrc_setup_procedure.cpp b/lib/rrc/ue/procedures/rrc_setup_procedure.cpp index 8063a1e20f..f692629c0a 100644 --- a/lib/rrc/ue/procedures/rrc_setup_procedure.cpp +++ b/lib/rrc/ue/procedures/rrc_setup_procedure.cpp @@ -22,14 +22,14 @@ rrc_setup_procedure::rrc_setup_procedure(rrc_ue_context_t& context const byte_buffer& du_to_cu_container_, rrc_ue_setup_proc_notifier& rrc_ue_notifier_, rrc_ue_control_message_handler& srb_notifier_, - rrc_ue_nas_notifier& nas_notifier_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_ue_event_manager& event_mng_, rrc_ue_logger& logger_) : context(context_), du_to_cu_container(du_to_cu_container_), rrc_ue(rrc_ue_notifier_), srb_notifier(srb_notifier_), - nas_notifier(nas_notifier_), + ngap_notifier(ngap_notifier_), event_mng(event_mng_), logger(logger_) { @@ -133,5 +133,5 @@ void rrc_setup_procedure::send_initial_ue_msg(const asn1::rrc_nr::rrc_setup_comp // TODO: Handle PLMN ID } - nas_notifier.on_initial_ue_message(init_ue_msg); + ngap_notifier.on_initial_ue_message(init_ue_msg); } diff --git a/lib/rrc/ue/procedures/rrc_setup_procedure.h b/lib/rrc/ue/procedures/rrc_setup_procedure.h index 17afc18e17..f49c3a275e 100644 --- a/lib/rrc/ue/procedures/rrc_setup_procedure.h +++ b/lib/rrc/ue/procedures/rrc_setup_procedure.h @@ -61,7 +61,7 @@ class rrc_setup_procedure const byte_buffer& du_to_cu_container_, rrc_ue_setup_proc_notifier& rrc_ue_notifier_, rrc_ue_control_message_handler& srb_notifier_, - rrc_ue_nas_notifier& nas_notifier_, + rrc_ue_ngap_notifier& ngap_notifier_, rrc_ue_event_manager& event_mng_, rrc_ue_logger& logger_); @@ -82,10 +82,10 @@ class rrc_setup_procedure rrc_ue_context_t& context; const byte_buffer& du_to_cu_container; - rrc_ue_setup_proc_notifier& rrc_ue; // handler to the parent RRC UE object - rrc_ue_control_message_handler& srb_notifier; // for creation of SRBs - rrc_ue_nas_notifier& nas_notifier; // notifier to the NGAP - rrc_ue_event_manager& event_mng; // event manager for the RRC UE entity + rrc_ue_setup_proc_notifier& rrc_ue; // handler to the parent RRC UE object + rrc_ue_control_message_handler& srb_notifier; // for creation of SRBs + rrc_ue_ngap_notifier& ngap_notifier; // notifier to the NGAP + rrc_ue_event_manager& event_mng; // event manager for the RRC UE entity rrc_ue_logger& logger; rrc_transaction transaction; diff --git a/lib/rrc/ue/rrc_ue_impl.cpp b/lib/rrc/ue/rrc_ue_impl.cpp index fdfde82cc7..4354e4fca1 100644 --- a/lib/rrc/ue/rrc_ue_impl.cpp +++ b/lib/rrc/ue/rrc_ue_impl.cpp @@ -19,9 +19,8 @@ using namespace srs_cu_cp; using namespace asn1::rrc_nr; rrc_ue_impl::rrc_ue_impl(rrc_pdu_f1ap_notifier& f1ap_pdu_notifier_, - rrc_ue_nas_notifier& nas_notif_, - rrc_ue_control_notifier& ngap_ctrl_notif_, - rrc_ue_context_update_notifier& cu_cp_notif_, + rrc_ue_ngap_notifier& ngap_notifier_, + rrc_ue_context_update_notifier& cu_cp_notifier_, rrc_ue_measurement_notifier& measurement_notifier_, rrc_ue_cu_cp_ue_notifier& cu_cp_ue_notifier_, const ue_index_t ue_index_, @@ -32,9 +31,8 @@ rrc_ue_impl::rrc_ue_impl(rrc_pdu_f1ap_notifier& f1ap_pdu_notifie std::optional rrc_context) : context(ue_index_, c_rnti_, cell_, cfg_, rrc_context), f1ap_pdu_notifier(f1ap_pdu_notifier_), - nas_notifier(nas_notif_), - ngap_ctrl_notifier(ngap_ctrl_notif_), - cu_cp_notifier(cu_cp_notif_), + ngap_notifier(ngap_notifier_), + cu_cp_notifier(cu_cp_notifier_), measurement_notifier(measurement_notifier_), cu_cp_ue_notifier(cu_cp_ue_notifier_), du_to_cu_container(du_to_cu_container_), diff --git a/lib/rrc/ue/rrc_ue_impl.h b/lib/rrc/ue/rrc_ue_impl.h index a19c9ddfb1..94ea0ad1f5 100644 --- a/lib/rrc/ue/rrc_ue_impl.h +++ b/lib/rrc/ue/rrc_ue_impl.h @@ -25,9 +25,8 @@ class rrc_ue_impl final : public rrc_ue_interface, public rrc_ue_controller { public: rrc_ue_impl(rrc_pdu_f1ap_notifier& f1ap_pdu_notifier_, - rrc_ue_nas_notifier& nas_notif_, - rrc_ue_control_notifier& ngap_ctrl_notif_, - rrc_ue_context_update_notifier& cu_cp_notif_, + rrc_ue_ngap_notifier& ngap_notifier_, + rrc_ue_context_update_notifier& cu_cp_notifier_, rrc_ue_measurement_notifier& measurement_notifier_, rrc_ue_cu_cp_ue_notifier& cu_cp_ue_notifier_, const ue_index_t ue_index_, @@ -103,8 +102,7 @@ class rrc_ue_impl final : public rrc_ue_interface, public rrc_ue_controller rrc_ue_context_t context; rrc_pdu_f1ap_notifier& f1ap_pdu_notifier; // PDU notifier to the F1AP - rrc_ue_nas_notifier& nas_notifier; // PDU notifier to the NGAP - rrc_ue_control_notifier& ngap_ctrl_notifier; // Control message notifier to the NGAP + rrc_ue_ngap_notifier& ngap_notifier; // notifier to the NGAP rrc_ue_context_update_notifier& cu_cp_notifier; // notifier to the CU-CP rrc_ue_measurement_notifier& measurement_notifier; // cell measurement notifier rrc_ue_cu_cp_ue_notifier& cu_cp_ue_notifier; // cu-cp ue notifier diff --git a/lib/rrc/ue/rrc_ue_message_handlers.cpp b/lib/rrc/ue/rrc_ue_message_handlers.cpp index 4c01e9205d..d4f2dc0f60 100644 --- a/lib/rrc/ue/rrc_ue_message_handlers.cpp +++ b/lib/rrc/ue/rrc_ue_message_handlers.cpp @@ -93,7 +93,7 @@ void rrc_ue_impl::handle_rrc_setup_request(const asn1::rrc_nr::rrc_setup_request // Launch RRC setup procedure cu_cp_ue_notifier.schedule_async_task(launch_async( - context, du_to_cu_container, *this, get_rrc_ue_control_message_handler(), nas_notifier, *event_mng, logger)); + context, du_to_cu_container, *this, get_rrc_ue_control_message_handler(), ngap_notifier, *event_mng, logger)); } void rrc_ue_impl::handle_rrc_reest_request(const asn1::rrc_nr::rrc_reest_request_s& msg) @@ -108,7 +108,7 @@ void rrc_ue_impl::handle_rrc_reest_request(const asn1::rrc_nr::rrc_reest_request get_rrc_ue_control_message_handler(), cu_cp_notifier, cu_cp_ue_notifier, - nas_notifier, + ngap_notifier, *event_mng, logger)); } @@ -157,8 +157,7 @@ void rrc_ue_impl::handle_pdu(const srb_id_t srb_id, byte_buffer rrc_pdu) case ul_dcch_msg_type_c::c1_c_::types_opts::rrc_recfg_complete: if (context.transfer_context.has_value() && context.transfer_context.value().is_inter_cu_handover) { logger.log_debug("Received a RRC Reconfiguration Complete during inter CU handover. Notifying NGAP"); - ngap_ctrl_notifier.on_inter_cu_ho_rrc_recfg_complete_received( - context.ue_index, context.cell.cgi, context.cell.tac); + ngap_notifier.on_inter_cu_ho_rrc_recfg_complete_received(context.ue_index, context.cell.cgi, context.cell.tac); context.transfer_context.value().is_inter_cu_handover = false; } else { handle_rrc_transaction_complete(ul_dcch_msg, ul_dcch_msg.msg.c1().rrc_recfg_complete().rrc_transaction_id); @@ -224,7 +223,7 @@ void rrc_ue_impl::handle_ul_info_transfer(const ul_info_transfer_ies_s& ul_info_ ul_nas_msg.user_location_info.tai.plmn_id = context.cell.cgi.plmn_id; ul_nas_msg.user_location_info.tai.tac = context.cell.tac; - nas_notifier.on_ul_nas_transport_message(ul_nas_msg); + ngap_notifier.on_ul_nas_transport_message(ul_nas_msg); } void rrc_ue_impl::handle_measurement_report(const asn1::rrc_nr::meas_report_s& msg) diff --git a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp index cf3a50d45d..9a41dc12bb 100644 --- a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp +++ b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp @@ -128,7 +128,6 @@ du_processor_test::du_processor_test() : cu_cp_notifier, f1ap_pdu_notifier, rrc_ue_ngap_notifier, - rrc_ue_ngap_notifier, rrc_du_cu_cp_notifier, *common_task_sched, ue_mng); diff --git a/tests/unittests/rrc/rrc_ue_test_helpers.h b/tests/unittests/rrc/rrc_ue_test_helpers.h index 47b1e4105b..5601bb441c 100644 --- a/tests/unittests/rrc/rrc_ue_test_helpers.h +++ b/tests/unittests/rrc/rrc_ue_test_helpers.h @@ -108,7 +108,6 @@ class rrc_ue_test_helper ue_cfg.meas_timings.push_back(meas_timing); ue_cfg.rrc_procedure_timeout_ms = cu_cp_cfg.rrc.rrc_procedure_timeout_ms; rrc_ue = std::make_unique(*rrc_ue_create_msg.f1ap_pdu_notifier, - rrc_ue_ngap_notifier, rrc_ue_ngap_notifier, *rrc_ue_create_msg.rrc_ue_cu_cp_notifier, *rrc_ue_create_msg.measurement_notifier, diff --git a/tests/unittests/rrc/test_helpers.h b/tests/unittests/rrc/test_helpers.h index d1d29862b2..a753121dcb 100644 --- a/tests/unittests/rrc/test_helpers.h +++ b/tests/unittests/rrc/test_helpers.h @@ -32,7 +32,7 @@ class dummy_rrc_f1ap_pdu_notifier : public rrc_pdu_f1ap_notifier srb_id_t last_srb_id; }; -class dummy_rrc_ue_ngap_adapter : public rrc_ue_nas_notifier, public rrc_ue_control_notifier +class dummy_rrc_ue_ngap_adapter : public rrc_ue_ngap_notifier { public: void set_ue_context_release_outcome(bool outcome) { ue_context_release_outcome = outcome; } From 1fb5c1f2fe254ff7aebd24e7112f2a218fe1e1c0 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 3 Sep 2024 15:15:04 +0200 Subject: [PATCH 030/174] cu_cp: make plmn mandatory at ue creation --- lib/cu_cp/cu_cp_impl.cpp | 2 +- lib/cu_cp/du_processor/du_processor_impl.cpp | 5 +- .../mobility/inter_du_handover_routine.cpp | 2 +- lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp | 17 ++----- lib/cu_cp/ue_manager/cu_cp_ue_impl.h | 9 ++-- lib/cu_cp/ue_manager/ue_manager_impl.cpp | 15 +++--- lib/cu_cp/ue_manager/ue_manager_impl.h | 15 ++---- .../cell_meas_manager_test.cpp | 19 ++++---- .../handover_reconfiguration_routine_test.cpp | 20 +++++--- .../cu_cp/ue_manager/ue_manager_test.cpp | 48 ++++++++++--------- .../e1ap/cu_cp/e1ap_cu_cp_test_helpers.cpp | 2 +- tests/unittests/ngap/ngap_test_helpers.cpp | 6 ++- tests/unittests/rrc/rrc_ue_test_helpers.h | 2 +- 13 files changed, 81 insertions(+), 81 deletions(-) diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 9e89af4c2c..a53ae7f76c 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -588,7 +588,7 @@ ue_index_t cu_cp_impl::handle_ue_index_allocation_request(const nr_cell_global_i logger.warning("Could not find DU for CGI={}", cgi.nci); return ue_index_t::invalid; } - return ue_mng.add_ue(du_index); + return ue_mng.add_ue(du_index, cgi.plmn_id); } void cu_cp_impl::handle_n2_disconnection() diff --git a/lib/cu_cp/du_processor/du_processor_impl.cpp b/lib/cu_cp/du_processor/du_processor_impl.cpp index 85497bd1b4..f659b0faf1 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.cpp +++ b/lib/cu_cp/du_processor/du_processor_impl.cpp @@ -206,7 +206,7 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c if (ue_index == ue_index_t::invalid) { // Add new CU-CP UE ue_index = ue_mng.add_ue( - cfg.du_index, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index, req.cgi.plmn_id); + cfg.du_index, req.cgi.plmn_id, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index); if (ue_index == ue_index_t::invalid) { logger.warning("CU-CP UE creation failed"); return make_unexpected(rrc_du_adapter.on_rrc_reject_required()); @@ -216,8 +216,7 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c /// NOTE: From this point on the UE exists in the UE manager and must be removed if any error occurs. } else { - ue = ue_mng.set_ue_du_context( - ue_index, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index, req.cgi.plmn_id); + ue = ue_mng.set_ue_du_context(ue_index, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index); if (ue == nullptr) { logger.warning("ue={}: Could not create UE context", ue_index); // A UE with the same PCI and RNTI already exists, so we don't remove it and only reject the new UE. diff --git a/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp b/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp index c2309bb731..a29959b89f 100644 --- a/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp +++ b/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp @@ -89,7 +89,7 @@ void inter_du_handover_routine::operator()(coro_context du_id_, std::optional pci_, std::optional c_rnti_, - std::optional pcell_index_, - std::optional plmn_) : + std::optional pcell_index_) : ue_index(ue_index_), task_sched(std::move(task_sched_)), up_mng(up_cfg), @@ -45,22 +45,15 @@ cu_cp_ue::cu_cp_ue(ue_index_t ue_index_, pcell_index = pcell_index_.value(); } - if (plmn_.has_value()) { - ue_ctxt.plmn = plmn_.value(); - } - ue_ctxt.du_idx = du_index_; + ue_ctxt.plmn = plmn_; rrc_ue_cu_cp_ue_ev_notifier.connect_ue(*this); ngap_cu_cp_ue_ev_notifier.connect_ue(*this); } /// \brief Update a UE with PCI and/or C-RNTI. -void cu_cp_ue::update_du_ue(gnb_du_id_t du_id_, - pci_t pci_, - rnti_t c_rnti_, - du_cell_index_t pcell_index_, - plmn_identity plmn_) +void cu_cp_ue::update_du_ue(gnb_du_id_t du_id_, pci_t pci_, rnti_t c_rnti_, du_cell_index_t pcell_index_) { if (du_id_ != gnb_du_id_t::invalid) { ue_ctxt.du_id = du_id_; @@ -77,8 +70,6 @@ void cu_cp_ue::update_du_ue(gnb_du_id_t du_id_, if (pcell_index_ != du_cell_index_t::invalid) { pcell_index = pcell_index_; } - - ue_ctxt.plmn = plmn_; } /// \brief Set/update the measurement context of the UE. diff --git a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h index 9fe22b79d1..acc4fe7256 100644 --- a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h +++ b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h @@ -28,10 +28,10 @@ namespace srs_cu_cp { /// \brief Context of a CU-CP UE. struct cu_cp_ue_context { du_index_t du_idx = du_index_t::invalid; + plmn_identity plmn = plmn_identity::test_value(); gnb_du_id_t du_id = gnb_du_id_t::invalid; ue_index_t ue_index = ue_index_t::invalid; rnti_t crnti = rnti_t::INVALID_RNTI; - plmn_identity plmn = plmn_identity::test_value(); /// \brief Flag to disable new UE reconfigurations. This can be used, for instance, to reconfigure UE contexts /// that are in the process of handover. bool reconfiguration_disabled = false; @@ -45,11 +45,11 @@ class cu_cp_ue : public cu_cp_ue_impl_interface const up_resource_manager_cfg& up_cfg, const security_manager_config& sec_cfg, ue_task_scheduler_impl task_sched_, + plmn_identity plmn_, std::optional du_id_ = std::nullopt, std::optional pci_ = std::nullopt, std::optional c_rnti_ = std::nullopt, - std::optional pcell_index_ = std::nullopt, - std::optional plmn_ = std::nullopt); + std::optional pcell_index_ = std::nullopt); /// \brief Cancel all pending UE tasks. void stop(); @@ -90,8 +90,7 @@ class cu_cp_ue : public cu_cp_ue_impl_interface void update_du_ue(gnb_du_id_t du_id_ = gnb_du_id_t::invalid, pci_t pci_ = INVALID_PCI, rnti_t c_rnti_ = rnti_t::INVALID_RNTI, - du_cell_index_t pcell_index_ = du_cell_index_t::invalid, - plmn_identity plmn_ = plmn_identity::test_value()); + du_cell_index_t pcell_index_ = du_cell_index_t::invalid); /// \brief Set/update the measurement context of the UE. void update_meas_context(cell_meas_manager_ue_context meas_ctxt); diff --git a/lib/cu_cp/ue_manager/ue_manager_impl.cpp b/lib/cu_cp/ue_manager/ue_manager_impl.cpp index 723bf50d85..29b79bf3c0 100644 --- a/lib/cu_cp/ue_manager/ue_manager_impl.cpp +++ b/lib/cu_cp/ue_manager/ue_manager_impl.cpp @@ -34,11 +34,11 @@ void ue_manager::stop() } ue_index_t ue_manager::add_ue(du_index_t du_index, + plmn_identity plmn, std::optional du_id, std::optional pci, std::optional rnti, - std::optional pcell_index, - std::optional plmn) + std::optional pcell_index) { if (du_index == du_index_t::invalid) { logger.warning("CU-CP UE creation Failed. Cause: Invalid DU index={}", du_index); @@ -90,15 +90,17 @@ ue_index_t ue_manager::add_ue(du_index_t du_index, std::piecewise_construct, std::forward_as_tuple(new_ue_index), std::forward_as_tuple( - new_ue_index, du_index, up_config, sec_config, std::move(ue_sched), du_id, pci, rnti, pcell_index, plmn)); + new_ue_index, du_index, up_config, sec_config, std::move(ue_sched), plmn, du_id, pci, rnti, pcell_index)); // Add PCI and RNTI to lookup. if (pci.has_value() && rnti.has_value()) { pci_rnti_to_ue_index.emplace(std::make_tuple(pci.value(), rnti.value()), new_ue_index); } - logger.info("ue={}{}{}{}{}: Created new CU-CP UE", + logger.info("ue={} du_index={} plmn={}{}{}{}{}: Created new CU-CP UE", new_ue_index, + du_index, + plmn, du_id.has_value() ? fmt::format(" gnb_du_id={}", du_id.value()) : "", pci.has_value() ? fmt::format(" pci={}", pci.value()) : "", rnti.has_value() ? fmt::format(" rnti={}", rnti.value()) : "", @@ -171,8 +173,7 @@ cu_cp_ue* ue_manager::set_ue_du_context(ue_index_t ue_index, gnb_du_id_t du_id, pci_t pci, rnti_t rnti, - du_cell_index_t pcell_index, - plmn_identity plmn) + du_cell_index_t pcell_index) { srsran_assert(ue_index != ue_index_t::invalid, "Invalid ue_index={}", ue_index); srsran_assert(pci != INVALID_PCI, "Invalid pci={}", pci); @@ -192,7 +193,7 @@ cu_cp_ue* ue_manager::set_ue_du_context(ue_index_t ue_index, } auto& ue = ues.at(ue_index); - ue.update_du_ue(du_id, pci, rnti, pcell_index, plmn); + ue.update_du_ue(du_id, pci, rnti, pcell_index); // Add PCI and RNTI to lookup. pci_rnti_to_ue_index.emplace(std::make_tuple(pci, rnti), ue_index); diff --git a/lib/cu_cp/ue_manager/ue_manager_impl.h b/lib/cu_cp/ue_manager/ue_manager_impl.h index 0cf8eba0c1..d8e31b3d7c 100644 --- a/lib/cu_cp/ue_manager/ue_manager_impl.h +++ b/lib/cu_cp/ue_manager/ue_manager_impl.h @@ -68,18 +68,18 @@ class ue_manager : public ue_metrics_handler /// \brief Allocate resources for the UE in the CU-CP. /// \param[in] du_index Index of the DU the UE is connected to. + /// \param[in] plmn The PLMN of the UE. /// \param[in] du_id The gNB-DU ID of the DU the UE is connected to. /// \param[in] pci The PCI of the cell the UE is connected to. /// \param[in] rnti The RNTI of the UE. /// \param[in] pcell_index The index of the PCell the UE is connected to. - /// \param[in] plmn The PLMN of the UE. /// \return ue_index of the created UE or ue_index_t::invalid in case of failure. ue_index_t add_ue(du_index_t du_index, + plmn_identity plmn, std::optional du_id = std::nullopt, std::optional pci = std::nullopt, std::optional rnti = std::nullopt, - std::optional pcell_index = std::nullopt, - std::optional plmn = std::nullopt); + std::optional pcell_index = std::nullopt); /// \brief Set the DU context of the UE. /// \param[in] ue_index Index of the UE. @@ -87,14 +87,9 @@ class ue_manager : public ue_metrics_handler /// \param[in] pci The PCI of the cell the UE is connected to. /// \param[in] rnti The RNTI of the UE. /// \param[in] pcell_index The index of the PCell the UE is connected to. - /// \param[in] plmn The PLMN of the UE. /// \return Pointer to the DU UE if found, nullptr otherwise. - cu_cp_ue* set_ue_du_context(ue_index_t ue_index, - gnb_du_id_t du_id, - pci_t pci, - rnti_t rnti, - du_cell_index_t pcell_index, - plmn_identity plmn); + cu_cp_ue* + set_ue_du_context(ue_index_t ue_index, gnb_du_id_t du_id, pci_t pci, rnti_t rnti, du_cell_index_t pcell_index); /// \brief Find the UE with the given UE index, thats DU context is set up. /// \param[in] ue_index Index of the UE to be found. diff --git a/tests/unittests/cu_cp/cell_meas_manager/cell_meas_manager_test.cpp b/tests/unittests/cu_cp/cell_meas_manager/cell_meas_manager_test.cpp index f2274223c8..dec7586f84 100644 --- a/tests/unittests/cu_cp/cell_meas_manager/cell_meas_manager_test.cpp +++ b/tests/unittests/cu_cp/cell_meas_manager/cell_meas_manager_test.cpp @@ -9,6 +9,7 @@ */ #include "cell_meas_manager_test_helpers.h" +#include "srsran/ran/plmn_identity.h" using namespace srsran; using namespace srs_cu_cp; @@ -46,7 +47,7 @@ TEST_F(cell_meas_manager_test, when_empty_config_is_used_then_no_neighbor_cells_ { create_empty_manager(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); nr_cell_identity nci = nr_cell_identity::create(0x19b0).value(); std::optional meas_cfg = manager->get_measurement_config(ue_index, nci); @@ -58,7 +59,7 @@ TEST_F(cell_meas_manager_test, when_serving_cell_not_found_no_neighbor_cells_are { create_default_manager(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); nr_cell_identity nci = nr_cell_identity::create(0x19b5).value(); std::optional meas_cfg = manager->get_measurement_config(ue_index, nci); @@ -70,7 +71,7 @@ TEST_F(cell_meas_manager_test, when_serving_cell_found_then_neighbor_cells_are_a { create_default_manager(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); for (unsigned nci_val = 0x19b0; nci_val < 0x19b2; ++nci_val) { std::optional meas_cfg = @@ -84,7 +85,7 @@ TEST_F(cell_meas_manager_test, when_inexisting_cell_config_is_updated_then_confi { create_default_manager(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); const nr_cell_identity nci = nr_cell_identity::create(0x19b1).value(); // get current config @@ -109,7 +110,7 @@ TEST_F(cell_meas_manager_test, when_incomplete_cell_config_is_updated_then_valid { create_default_manager(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); const nr_cell_identity nci = nr_cell_identity::create(0x19b1).value(); // get current config @@ -133,7 +134,7 @@ TEST_F(cell_meas_manager_test, when_empty_cell_config_is_used_then_meas_cfg_is_n // Create a manager without ncells and without report config. create_manager_without_ncells_and_periodic_report(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); nr_cell_identity nci = nr_cell_identity::create(0x19b0).value(); std::optional meas_cfg = manager->get_measurement_config(ue_index, nci); @@ -145,7 +146,7 @@ TEST_F(cell_meas_manager_test, when_old_meas_config_is_provided_old_ids_are_remo { create_default_manager(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); const nr_cell_identity initial_nci = nr_cell_identity::create(0x19b0).value(); // Make sure meas_cfg is created (no previous meas config provided) @@ -175,7 +176,7 @@ TEST_F(cell_meas_manager_test, when_only_event_based_reports_configured_then_mea { create_manager_with_incomplete_cells_and_periodic_report_at_target_cell(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); const nr_cell_identity initial_nci = nr_cell_identity::create(0x19b0).value(); const nr_cell_identity target_nci = nr_cell_identity::create(0x19b1).value(); @@ -227,7 +228,7 @@ TEST_F(cell_meas_manager_test, when_invalid_cell_config_update_received_then_con { create_manager_with_incomplete_cells_and_periodic_report_at_target_cell(); - ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0)); + ue_index_t ue_index = ue_mng.add_ue(uint_to_du_index(0), plmn_identity::test_value()); const nr_cell_identity initial_nci = nr_cell_identity::create(0x19b0).value(); const nr_cell_identity target_nci = nr_cell_identity::create(0x19b1).value(); diff --git a/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp b/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp index 1e25d8a1b2..0a15f15eb2 100644 --- a/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp +++ b/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp @@ -25,16 +25,24 @@ class handover_reconfiguration_routine_test : public mobility_test void create_ues(bool procedure_outcome, unsigned transaction_id_) { - ue_index_t source_ue_index = - get_ue_manager()->add_ue(source_du_index, int_to_gnb_du_id(0), source_pci, source_rnti, du_cell_index_t::min); - source_ue = get_ue_manager()->find_ue(source_ue_index); + ue_index_t source_ue_index = get_ue_manager()->add_ue(source_du_index, + plmn_identity::test_value(), + int_to_gnb_du_id(0), + source_pci, + source_rnti, + du_cell_index_t::min); + source_ue = get_ue_manager()->find_ue(source_ue_index); ASSERT_NE(source_ue, nullptr); source_rrc_ue_notifier.set_transaction_id(transaction_id_); source_ue->set_rrc_ue_notifier(source_rrc_ue_notifier); - ue_index_t target_ue_index = - get_ue_manager()->add_ue(target_du_index, int_to_gnb_du_id(0), target_pci, target_rnti, du_cell_index_t::min); - target_ue = get_ue_manager()->find_ue(target_ue_index); + ue_index_t target_ue_index = get_ue_manager()->add_ue(target_du_index, + plmn_identity::test_value(), + int_to_gnb_du_id(0), + target_pci, + target_rnti, + du_cell_index_t::min); + target_ue = get_ue_manager()->find_ue(target_ue_index); ASSERT_NE(target_ue, nullptr); cu_cp_handler.set_rrc_reconfiguration_outcome(procedure_outcome); target_ue->set_rrc_ue_notifier(target_rrc_ue_notifier); diff --git a/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp b/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp index 7c668fda67..5f0c80a9e6 100644 --- a/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp +++ b/tests/unittests/cu_cp/ue_manager/ue_manager_test.cpp @@ -30,7 +30,7 @@ TEST_F(ue_manager_test, when_multiple_ue_indexes_allocated_then_ue_indexes_valid for (unsigned it = 0; it < cu_cp_cfg.admission.max_nof_ues; it++) { // Check that the ue index is valid - ASSERT_NE(ue_mng.add_ue(du_index), ue_index_t::invalid); + ASSERT_NE(ue_mng.add_ue(du_index, plmn_identity::test_value()), ue_index_t::invalid); } } @@ -45,7 +45,7 @@ TEST_F(ue_manager_test, when_more_than_max_ue_indexes_allocated_then_ue_index_in for (unsigned it = 0; it < cu_cp_cfg.admission.max_nof_ues; it++) { // Check that the ue index is valid - ASSERT_NE(ue_mng.add_ue(du_index), ue_index_t::invalid); + ASSERT_NE(ue_mng.add_ue(du_index, plmn_identity::test_value()), ue_index_t::invalid); } // reset log level @@ -53,7 +53,7 @@ TEST_F(ue_manager_test, when_more_than_max_ue_indexes_allocated_then_ue_index_in test_logger.set_level(srslog::basic_levels::debug); // Allocate additional ue index - ASSERT_EQ(ue_mng.add_ue(du_index), ue_index_t::invalid); + ASSERT_EQ(ue_mng.add_ue(du_index, plmn_identity::test_value()), ue_index_t::invalid); } /// Test successful creation of a DU UE @@ -62,8 +62,9 @@ TEST_F(ue_manager_test, when_valid_du_context_added_at_creation_then_ue_added) du_index_t du_index = du_index_t::min; rnti_t rnti = to_rnti(0x4601); du_cell_index_t pcell_index = du_cell_index_t::min; - ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); - auto* ue = ue_mng.find_ue(ue_index); + ue_index_t ue_index = + ue_mng.add_ue(du_index, plmn_identity::test_value(), gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + auto* ue = ue_mng.find_ue(ue_index); // check that the UE has been created ASSERT_NE(ue, nullptr); @@ -95,12 +96,11 @@ TEST_F(ue_manager_test, when_valid_du_context_added_at_creation_then_ue_added) TEST_F(ue_manager_test, when_du_context_valid_then_ue_updated) { du_index_t du_index = du_index_t::min; - ue_index_t ue_index = ue_mng.add_ue(du_index); + ue_index_t ue_index = ue_mng.add_ue(du_index, plmn_identity::test_value()); rnti_t rnti = to_rnti(0x4601); du_cell_index_t pcell_index = du_cell_index_t::min; - plmn_identity plmn = plmn_identity::test_value(); - auto* ue = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index, plmn); + auto* ue = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); // check that the UE has been created ASSERT_NE(ue, nullptr); @@ -134,8 +134,9 @@ TEST_F(ue_manager_test, when_ue_index_invalid_then_ue_not_found) du_index_t du_index = du_index_t::min; rnti_t rnti = to_rnti(0x4601); du_cell_index_t pcell_index = du_cell_index_t::min; - ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); - auto* ue = ue_mng.find_ue(ue_index); + ue_index_t ue_index = + ue_mng.add_ue(du_index, plmn_identity::test_value(), gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + auto* ue = ue_mng.find_ue(ue_index); // check that the UE has been created ASSERT_NE(ue, nullptr); @@ -150,13 +151,13 @@ TEST_F(ue_manager_test, when_rnti_already_exits_then_ue_not_added) du_index_t du_index = du_index_t::min; rnti_t rnti = to_rnti(0x4601); du_cell_index_t pcell_index = du_cell_index_t::min; - plmn_identity plmn = plmn_identity::test_value(); - ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index, plmn); + ue_index_t ue_index = + ue_mng.add_ue(du_index, plmn_identity::test_value(), gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); // check that the number of DU UEs is 1 ASSERT_EQ(ue_mng.get_nof_du_ues(du_index), 1U); - auto* ue2 = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index, plmn); + auto* ue2 = ue_mng.set_ue_du_context(ue_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); // check that the UE has not been added ASSERT_EQ(ue2, nullptr); @@ -169,8 +170,9 @@ TEST_F(ue_manager_test, when_ue_exists_then_removal_successful) du_index_t du_index = du_index_t::min; rnti_t rnti = to_rnti(0x4601); du_cell_index_t pcell_index = du_cell_index_t::min; - ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); - auto* ue = ue_mng.find_ue(ue_index); + ue_index_t ue_index = + ue_mng.add_ue(du_index, plmn_identity::test_value(), gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + auto* ue = ue_mng.find_ue(ue_index); ue_mng.remove_ue(ue->get_ue_index()); @@ -191,9 +193,10 @@ TEST_F(ue_manager_test, when_multiple_ues_added_then_ues_exist) for (unsigned it = to_value(rnti_t::MIN_CRNTI); it < unsigned(to_value(rnti_t::MIN_CRNTI) + cu_cp_cfg.admission.max_nof_ues); it++) { - rnti_t rnti = to_rnti(it); - ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); - auto* ue = ue_mng.find_ue(ue_index); + rnti_t rnti = to_rnti(it); + ue_index_t ue_index = + ue_mng.add_ue(du_index, plmn_identity::test_value(), gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + auto* ue = ue_mng.find_ue(ue_index); // check that the UE has been created ASSERT_NE(ue, nullptr); @@ -235,9 +238,10 @@ TEST_F(ue_manager_test, when_more_than_max_ues_added_then_ue_not_created) for (unsigned it = to_value(rnti_t::MIN_CRNTI); it < unsigned(to_value(rnti_t::MIN_CRNTI) + cu_cp_cfg.admission.max_nof_ues); it++) { - rnti_t rnti = to_rnti(it); - ue_index_t ue_index = ue_mng.add_ue(du_index, gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); - auto* ue = ue_mng.find_ue(ue_index); + rnti_t rnti = to_rnti(it); + ue_index_t ue_index = + ue_mng.add_ue(du_index, plmn_identity::test_value(), gnb_du_id_t::min, MIN_PCI, rnti, pcell_index); + auto* ue = ue_mng.find_ue(ue_index); // check that the UE has been created ASSERT_NE(ue, nullptr); @@ -266,7 +270,7 @@ TEST_F(ue_manager_test, when_more_than_max_ues_added_then_ue_not_created) // check that the maximum number of DU UEs has been reached ASSERT_EQ(ue_mng.get_nof_du_ues(du_index), cu_cp_cfg.admission.max_nof_ues); - ue_index_t ue_index = ue_mng.add_ue(du_index); + ue_index_t ue_index = ue_mng.add_ue(du_index, plmn_identity::test_value()); ASSERT_EQ(ue_index, ue_index_t::invalid); // check that the UE has not been added diff --git a/tests/unittests/e1ap/cu_cp/e1ap_cu_cp_test_helpers.cpp b/tests/unittests/e1ap/cu_cp/e1ap_cu_cp_test_helpers.cpp index e6cb11aaeb..c7fec1a53c 100644 --- a/tests/unittests/e1ap/cu_cp/e1ap_cu_cp_test_helpers.cpp +++ b/tests/unittests/e1ap/cu_cp/e1ap_cu_cp_test_helpers.cpp @@ -71,7 +71,7 @@ void e1ap_cu_cp_test::run_bearer_context_setup(ue_index_t ue_index, gnb_cu_up_ue e1ap_cu_cp_test::test_ue& e1ap_cu_cp_test::create_ue() { - ue_index_t ue_index = ue_mng.add_ue(du_index_t::min); + ue_index_t ue_index = ue_mng.add_ue(du_index_t::min, plmn_identity::test_value()); auto request = generate_bearer_context_setup_request(ue_index); run_bearer_context_setup(request.ue_index, diff --git a/tests/unittests/ngap/ngap_test_helpers.cpp b/tests/unittests/ngap/ngap_test_helpers.cpp index a411c7b047..cd0392c967 100644 --- a/tests/unittests/ngap/ngap_test_helpers.cpp +++ b/tests/unittests/ngap/ngap_test_helpers.cpp @@ -57,7 +57,8 @@ ngap_test::~ngap_test() ue_index_t ngap_test::create_ue(rnti_t rnti) { // Create UE in UE manager - ue_index_t ue_index = ue_mng.add_ue(du_index_t::min, int_to_gnb_du_id(0), MIN_PCI, rnti, du_cell_index_t::min); + ue_index_t ue_index = ue_mng.add_ue( + du_index_t::min, plmn_identity::test_value(), int_to_gnb_du_id(0), MIN_PCI, rnti, du_cell_index_t::min); if (ue_index == ue_index_t::invalid) { test_logger.error( "Failed to create UE with pci={} rnti={} pcell_index={}", MIN_PCI, rnti_t::MIN_CRNTI, du_cell_index_t::min); @@ -83,7 +84,8 @@ ue_index_t ngap_test::create_ue(rnti_t rnti) ue_index_t ngap_test::create_ue_without_init_ue_message(rnti_t rnti) { // Create UE in UE manager - ue_index_t ue_index = ue_mng.add_ue(du_index_t::min, int_to_gnb_du_id(0), MIN_PCI, rnti, du_cell_index_t::min); + ue_index_t ue_index = ue_mng.add_ue( + du_index_t::min, plmn_identity::test_value(), int_to_gnb_du_id(0), MIN_PCI, rnti, du_cell_index_t::min); if (ue_index == ue_index_t::invalid) { test_logger.error( "Failed to create UE with pci={} rnti={} pcell_index={}", MIN_PCI, rnti_t::MIN_CRNTI, du_cell_index_t::min); diff --git a/tests/unittests/rrc/rrc_ue_test_helpers.h b/tests/unittests/rrc/rrc_ue_test_helpers.h index 5601bb441c..35a17fce52 100644 --- a/tests/unittests/rrc/rrc_ue_test_helpers.h +++ b/tests/unittests/rrc/rrc_ue_test_helpers.h @@ -80,7 +80,7 @@ class rrc_ue_test_helper void init() { // add UE to UE manager - allocated_ue_index = ue_mng.add_ue(du_index_t::min); + allocated_ue_index = ue_mng.add_ue(du_index_t::min, plmn_identity::test_value()); // create RRC UE rrc_ue_creation_message rrc_ue_create_msg{}; From 1c19b834e6f2edbadf3f3292e7fda51f2949c412 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 3 Sep 2024 16:08:23 +0200 Subject: [PATCH 031/174] cu_cp: move rrc to ngap adapter to ue --- include/srsran/rrc/rrc_du.h | 1 + include/srsran/rrc/rrc_du_factory.h | 1 - lib/cu_cp/adapters/rrc_ue_adapters.h | 13 +++++-------- lib/cu_cp/cu_cp_impl.cpp | 5 +++-- lib/cu_cp/cu_cp_impl.h | 3 --- lib/cu_cp/du_processor/du_processor_factory.cpp | 2 -- lib/cu_cp/du_processor/du_processor_factory.h | 1 - lib/cu_cp/du_processor/du_processor_impl.cpp | 5 ++--- lib/cu_cp/du_processor/du_processor_impl.h | 2 -- lib/cu_cp/du_processor/du_processor_repository.cpp | 1 - lib/cu_cp/du_processor/du_processor_repository.h | 1 - lib/cu_cp/ue_manager/cu_cp_ue_impl.h | 6 +++++- lib/cu_cp/ue_manager/ue_manager_impl.h | 8 ++++++++ lib/rrc/rrc_du_factory.cpp | 2 +- lib/rrc/rrc_du_impl.cpp | 11 +++-------- lib/rrc/rrc_du_impl.h | 5 +---- .../du_processor/du_processor_test_helpers.cpp | 9 ++------- .../cu_cp/du_processor/du_processor_test_helpers.h | 1 - 18 files changed, 31 insertions(+), 46 deletions(-) diff --git a/include/srsran/rrc/rrc_du.h b/include/srsran/rrc/rrc_du.h index 521979d20b..23f3d06b06 100644 --- a/include/srsran/rrc/rrc_du.h +++ b/include/srsran/rrc/rrc_du.h @@ -36,6 +36,7 @@ struct rrc_ue_creation_message { rnti_t c_rnti; rrc_cell_context cell; rrc_pdu_f1ap_notifier* f1ap_pdu_notifier; + rrc_ue_ngap_notifier* ngap_notifier; rrc_ue_context_update_notifier* rrc_ue_cu_cp_notifier; rrc_ue_measurement_notifier* measurement_notifier; rrc_ue_cu_cp_ue_notifier* cu_cp_ue_notifier; diff --git a/include/srsran/rrc/rrc_du_factory.h b/include/srsran/rrc/rrc_du_factory.h index 6b254f6afa..f95aff8691 100644 --- a/include/srsran/rrc/rrc_du_factory.h +++ b/include/srsran/rrc/rrc_du_factory.h @@ -22,7 +22,6 @@ struct ue_context; struct rrc_du_creation_message { const rrc_cfg_t& cfg; - rrc_ue_ngap_notifier& ngap_notifier; rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier; }; diff --git a/lib/cu_cp/adapters/rrc_ue_adapters.h b/lib/cu_cp/adapters/rrc_ue_adapters.h index 91565683b4..e7e61ee1df 100644 --- a/lib/cu_cp/adapters/rrc_ue_adapters.h +++ b/lib/cu_cp/adapters/rrc_ue_adapters.h @@ -52,19 +52,17 @@ class rrc_ue_f1ap_pdu_adapter : public rrc_pdu_f1ap_notifier class rrc_ue_ngap_adapter : public rrc_ue_ngap_notifier { public: - explicit rrc_ue_ngap_adapter(ngap_repository& ngap_db_) : ngap_db(ngap_db_) {} + void connect_ngap(ngap_interface* ngap_) { ngap = ngap_; } void on_initial_ue_message(const cu_cp_initial_ue_message& msg) override { - auto* ngap = ngap_db.find_ngap(msg.plmn); - srsran_assert(ngap != nullptr, "NGAP for PLMN={} not found", msg.plmn); + srsran_assert(ngap != nullptr, "ue={}: NGAP for not found", msg.ue_index); ngap->get_ngap_nas_message_handler().handle_initial_ue_message(msg); } void on_ul_nas_transport_message(const cu_cp_ul_nas_transport& msg) override { - auto* ngap = ngap_db.find_ngap(msg.plmn); - srsran_assert(ngap != nullptr, "NGAP for PLMN={} not found", msg.plmn); + srsran_assert(ngap != nullptr, "ue={}: NGAP for not found", msg.ue_index); ngap->get_ngap_nas_message_handler().handle_ul_nas_transport_message(msg); } @@ -72,13 +70,12 @@ class rrc_ue_ngap_adapter : public rrc_ue_ngap_notifier const nr_cell_global_id_t& cgi, const unsigned tac) override { - auto* ngap = ngap_db.find_ngap(cgi.plmn_id); - srsran_assert(ngap != nullptr, "NGAP for PLMN={} not found", cgi.plmn_id); + srsran_assert(ngap != nullptr, "ue={}: NGAP for not found", ue_index); ngap->get_ngap_control_message_handler().handle_inter_cu_ho_rrc_recfg_complete(ue_index, cgi, tac); } private: - ngap_repository& ngap_db; + ngap_interface* ngap = nullptr; }; /// Adapter between RRC UE and CU-CP UE diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index a53ae7f76c..6fe115b150 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -54,7 +54,6 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : *this, get_cu_cp_ue_removal_handler(), get_cu_cp_ue_context_handler(), - rrc_ue_ngap_notifier, common_task_sched, ue_mng, rrc_du_cu_cp_notifier, @@ -63,7 +62,6 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : cu_up_db(cu_up_repository_config{cfg, e1ap_ev_notifier, srslog::fetch_basic_logger("CU-CP")}), paging_handler(du_db), ngap_db(ngap_repository_config{cfg, get_cu_cp_ngap_handler(), paging_handler, srslog::fetch_basic_logger("CU-CP")}), - rrc_ue_ngap_notifier(ngap_db), metrics_hdlr( std::make_unique(*cfg.services.cu_cp_executor, *cfg.services.timers, ue_mng, du_db)) { @@ -699,6 +697,9 @@ void cu_cp_impl::handle_rrc_ue_creation(ue_index_t ue_index, rrc_ue_interface& r // Connect RRC UE to NGAP to RRC UE adapter ue_mng.get_ngap_rrc_ue_adapter(ue_index).connect_rrc_ue(rrc_ue.get_rrc_ngap_message_handler()); + // Connect NGAP to RRC UE to NGAP adapter + ue_mng.get_rrc_ue_ngap_adapter(ue_index).connect_ngap(ngap_db.find_ngap(ue->get_ue_context().plmn)); + // Connect cu-cp to rrc ue adapters ue_mng.get_rrc_ue_cu_cp_adapter(ue_index).connect_cu_cp(get_cu_cp_rrc_ue_interface(), get_cu_cp_ue_removal_handler(), diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index 060f69d65e..3d1e1c1a0c 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -194,9 +194,6 @@ class cu_cp_impl final : public cu_cp, // AMF connections beeing managed by the CU-CP. ngap_repository ngap_db; - // RRC UE to NGAP adapter - rrc_ue_ngap_adapter rrc_ue_ngap_notifier; - // Handler of the CU-CP connections to other remote nodes (e.g. AMF, CU-UPs, DUs). std::unique_ptr controller; diff --git a/lib/cu_cp/du_processor/du_processor_factory.cpp b/lib/cu_cp/du_processor/du_processor_factory.cpp index c25439207a..6a4a7f6878 100644 --- a/lib/cu_cp/du_processor/du_processor_factory.cpp +++ b/lib/cu_cp/du_processor/du_processor_factory.cpp @@ -21,7 +21,6 @@ std::unique_ptr srsran::srs_cu_cp::create_du_processor(du_processor_config_t du_processor_config, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_) @@ -29,7 +28,6 @@ srsran::srs_cu_cp::create_du_processor(du_processor_config_t du_pr auto du_processor = std::make_unique(std::move(du_processor_config), cu_cp_notifier_, f1ap_pdu_notifier_, - ngap_notifier_, rrc_du_cu_cp_notifier, common_task_sched_, ue_mng_); diff --git a/lib/cu_cp/du_processor/du_processor_factory.h b/lib/cu_cp/du_processor/du_processor_factory.h index d72036ba0e..70b55770f1 100644 --- a/lib/cu_cp/du_processor/du_processor_factory.h +++ b/lib/cu_cp/du_processor/du_processor_factory.h @@ -27,7 +27,6 @@ class common_task_scheduler; std::unique_ptr create_du_processor(du_processor_config_t du_processor_config_, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_); diff --git a/lib/cu_cp/du_processor/du_processor_impl.cpp b/lib/cu_cp/du_processor/du_processor_impl.cpp index f659b0faf1..29e07f6434 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.cpp +++ b/lib/cu_cp/du_processor/du_processor_impl.cpp @@ -76,14 +76,12 @@ class du_processor_impl::f1ap_du_processor_adapter : public f1ap_du_processor_no du_processor_impl::du_processor_impl(du_processor_config_t du_processor_config_, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_) : cfg(std::move(du_processor_config_)), cu_cp_notifier(cu_cp_notifier_), f1ap_pdu_notifier(f1ap_pdu_notifier_), - ngap_notifier(ngap_notifier_), ue_mng(ue_mng_), f1ap_ev_notifier(std::make_unique(*this, common_task_sched_)) { @@ -96,7 +94,7 @@ du_processor_impl::du_processor_impl(du_processor_config_t du_proc f1ap_ue_context_notifier.connect_f1(f1ap->get_f1ap_ue_context_manager()); // create RRC - rrc_du_creation_message du_creation_req{create_rrc_config(cfg.cu_cp_cfg), ngap_notifier, rrc_du_cu_cp_notifier}; + rrc_du_creation_message du_creation_req{create_rrc_config(cfg.cu_cp_cfg), rrc_du_cu_cp_notifier}; rrc = create_rrc_du(du_creation_req); rrc_du_adapter.connect_rrc_du(rrc->get_rrc_du_cell_manager(), rrc->get_rrc_du_ue_repository()); } @@ -164,6 +162,7 @@ bool du_processor_impl::create_rrc_ue(cu_cp_ue& ue, rrc_ue_create_msg.cell.pci = cell.pci; rrc_ue_create_msg.cell.bands = cell.bands; rrc_ue_create_msg.f1ap_pdu_notifier = &rrc_ue_f1ap_adapters.at(ue.get_ue_index()); + rrc_ue_create_msg.ngap_notifier = &ue.get_rrc_ue_ngap_adapter(); rrc_ue_create_msg.rrc_ue_cu_cp_notifier = &ue.get_rrc_ue_context_update_notifier(); rrc_ue_create_msg.measurement_notifier = &ue.get_rrc_ue_measurement_notifier(); rrc_ue_create_msg.cu_cp_ue_notifier = &ue.get_rrc_ue_cu_cp_ue_notifier(); diff --git a/lib/cu_cp/du_processor/du_processor_impl.h b/lib/cu_cp/du_processor/du_processor_impl.h index d73594632e..2b5c563783 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.h +++ b/lib/cu_cp/du_processor/du_processor_impl.h @@ -33,7 +33,6 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public du_processor_impl(du_processor_config_t du_processor_config_, du_processor_cu_cp_notifier& cu_cp_notifier_, f1ap_message_notifier& f1ap_pdu_notifier_, - rrc_ue_ngap_notifier& ngap_notifier_, rrc_du_measurement_config_notifier& rrc_du_cu_cp_notifier, common_task_scheduler& common_task_sched_, ue_manager& ue_mng_); @@ -94,7 +93,6 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public du_processor_cu_cp_notifier& cu_cp_notifier; f1ap_message_notifier& f1ap_pdu_notifier; - rrc_ue_ngap_notifier& ngap_notifier; ue_manager& ue_mng; du_processor_f1ap_ue_context_adapter f1ap_ue_context_notifier; diff --git a/lib/cu_cp/du_processor/du_processor_repository.cpp b/lib/cu_cp/du_processor/du_processor_repository.cpp index adda220c6e..d731985124 100644 --- a/lib/cu_cp/du_processor/du_processor_repository.cpp +++ b/lib/cu_cp/du_processor/du_processor_repository.cpp @@ -49,7 +49,6 @@ du_index_t du_processor_repository::add_du(std::unique_ptr du = create_du_processor(std::move(du_cfg), du_ctxt.du_to_cu_cp_notifier, *du_ctxt.f1ap_tx_pdu_notifier, - cfg.ngap_notifier, cfg.meas_config_notifier, cfg.common_task_sched, cfg.ue_mng); diff --git a/lib/cu_cp/du_processor/du_processor_repository.h b/lib/cu_cp/du_processor/du_processor_repository.h index 52b73cce7a..f24200c9dd 100644 --- a/lib/cu_cp/du_processor/du_processor_repository.h +++ b/lib/cu_cp/du_processor/du_processor_repository.h @@ -33,7 +33,6 @@ struct du_repository_config { cu_cp_du_event_handler& cu_cp_du_handler; cu_cp_ue_removal_handler& ue_removal_handler; cu_cp_ue_context_manipulation_handler& ue_context_handler; - rrc_ue_ngap_notifier& ngap_notifier; common_task_scheduler& common_task_sched; ue_manager& ue_mng; rrc_du_measurement_config_notifier& meas_config_notifier; diff --git a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h index acc4fe7256..bf2504f9d0 100644 --- a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h +++ b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h @@ -126,6 +126,9 @@ class cu_cp_ue : public cu_cp_ue_impl_interface /// \brief Get the NGAP to RRC UE adapter of the UE. ngap_rrc_ue_adapter& get_ngap_rrc_ue_adapter() { return ngap_rrc_ue_ev_notifier; } + /// \brief Get the RRC UE to NGAP adapter of the UE. + rrc_ue_ngap_adapter& get_rrc_ue_ngap_adapter() { return rrc_ue_ngap_ev_notifier; } + /// \brief Get the RRC to CU-CP adapter of the UE. rrc_ue_cu_cp_adapter& get_rrc_ue_cu_cp_adapter() { return rrc_ue_cu_cp_ev_notifier; } @@ -148,7 +151,8 @@ class cu_cp_ue : public cu_cp_ue_impl_interface du_processor_rrc_ue_notifier* rrc_ue_notifier = nullptr; // rrc ue - rrc_ue_interface* rrc_ue = nullptr; + rrc_ue_interface* rrc_ue = nullptr; + rrc_ue_ngap_adapter rrc_ue_ngap_ev_notifier; // ngap ue context ngap_cu_cp_ue_adapter ngap_cu_cp_ue_ev_notifier; diff --git a/lib/cu_cp/ue_manager/ue_manager_impl.h b/lib/cu_cp/ue_manager/ue_manager_impl.h index d8e31b3d7c..e23b53f10d 100644 --- a/lib/cu_cp/ue_manager/ue_manager_impl.h +++ b/lib/cu_cp/ue_manager/ue_manager_impl.h @@ -112,6 +112,14 @@ class ue_manager : public ue_metrics_handler return ues.at(ue_index).get_ngap_rrc_ue_adapter(); } + rrc_ue_ngap_adapter& get_rrc_ue_ngap_adapter(ue_index_t ue_index) + { + srsran_assert(ue_index != ue_index_t::invalid, "Invalid ue_index={}", ue_index); + srsran_assert(ues.find(ue_index) != ues.end(), "UE with ue_index={} does not exist", ue_index); + + return ues.at(ue_index).get_rrc_ue_ngap_adapter(); + } + rrc_ue_cu_cp_adapter& get_rrc_ue_cu_cp_adapter(ue_index_t ue_index) { srsran_assert(ue_index != ue_index_t::invalid, "Invalid ue_index={}", ue_index); diff --git a/lib/rrc/rrc_du_factory.cpp b/lib/rrc/rrc_du_factory.cpp index 39a810bd62..319cbf6be3 100644 --- a/lib/rrc/rrc_du_factory.cpp +++ b/lib/rrc/rrc_du_factory.cpp @@ -17,5 +17,5 @@ using namespace srs_cu_cp; std::unique_ptr srsran::srs_cu_cp::create_rrc_du(const rrc_du_creation_message& msg) { - return std::make_unique(msg.cfg, msg.ngap_notifier, msg.rrc_du_cu_cp_notifier); + return std::make_unique(msg.cfg, msg.rrc_du_cu_cp_notifier); } diff --git a/lib/rrc/rrc_du_impl.cpp b/lib/rrc/rrc_du_impl.cpp index 05dbaec7f2..c6f171fd57 100644 --- a/lib/rrc/rrc_du_impl.cpp +++ b/lib/rrc/rrc_du_impl.cpp @@ -19,13 +19,8 @@ using namespace srsran; using namespace srs_cu_cp; using namespace asn1::rrc_nr; -rrc_du_impl::rrc_du_impl(const rrc_cfg_t& cfg_, - rrc_ue_ngap_notifier& ngap_notifier_, - rrc_du_measurement_config_notifier& meas_config_notifier_) : - cfg(cfg_), - ngap_notifier(ngap_notifier_), - meas_config_notifier(meas_config_notifier_), - logger(srslog::fetch_basic_logger("RRC", false)) +rrc_du_impl::rrc_du_impl(const rrc_cfg_t& cfg_, rrc_du_measurement_config_notifier& meas_config_notifier_) : + cfg(cfg_), meas_config_notifier(meas_config_notifier_), logger(srslog::fetch_basic_logger("RRC", false)) { for (const auto& qos : cfg.drb_config) { logger.debug("5QI DRB config: {} {}", qos.first, qos.second.pdcp); @@ -135,7 +130,7 @@ rrc_ue_interface* rrc_du_impl::add_ue(const rrc_ue_creation_message& msg) auto res = ue_db.emplace(ue_index, std::make_unique(*msg.f1ap_pdu_notifier, - ngap_notifier, + *msg.ngap_notifier, *msg.rrc_ue_cu_cp_notifier, *msg.measurement_notifier, *msg.cu_cp_ue_notifier, diff --git a/lib/rrc/rrc_du_impl.h b/lib/rrc/rrc_du_impl.h index 87609749b8..e5f8a2eb92 100644 --- a/lib/rrc/rrc_du_impl.h +++ b/lib/rrc/rrc_du_impl.h @@ -24,9 +24,7 @@ namespace srs_cu_cp { class rrc_du_impl : public rrc_du { public: - rrc_du_impl(const rrc_cfg_t& cfg_, - rrc_ue_ngap_notifier& ngap_notifier_, - rrc_du_measurement_config_notifier& meas_config_notifier_); + rrc_du_impl(const rrc_cfg_t& cfg_, rrc_du_measurement_config_notifier& meas_config_notifier_); ~rrc_du_impl() = default; // rrc_du_cell_manager @@ -59,7 +57,6 @@ class rrc_du_impl : public rrc_du // helpers const rrc_cfg_t cfg; - rrc_ue_ngap_notifier& ngap_notifier; // notifier to the NGAP rrc_du_measurement_config_notifier& meas_config_notifier; // notifier to the CU-CP srslog::basic_logger& logger; diff --git a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp index 9a41dc12bb..053ff49e94 100644 --- a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp +++ b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.cpp @@ -124,13 +124,8 @@ du_processor_test::du_processor_test() : srslog::fetch_basic_logger("CU-CP"), &du_conn_notifier, du_cfg_mgr.create_du_handler()}; - du_processor_obj = create_du_processor(std::move(du_cfg), - cu_cp_notifier, - f1ap_pdu_notifier, - rrc_ue_ngap_notifier, - rrc_du_cu_cp_notifier, - *common_task_sched, - ue_mng); + du_processor_obj = create_du_processor( + std::move(du_cfg), cu_cp_notifier, f1ap_pdu_notifier, rrc_du_cu_cp_notifier, *common_task_sched, ue_mng); cu_cp_event_handler = std::make_unique(ue_mng); cu_cp_notifier.attach_handler(&*cu_cp_event_handler, nullptr); diff --git a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.h b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.h index d9485ebe12..5796f09afc 100644 --- a/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.h +++ b/tests/unittests/cu_cp/du_processor/du_processor_test_helpers.h @@ -45,7 +45,6 @@ class du_processor_test : public ::testing::Test dummy_du_processor_cu_cp_notifier cu_cp_notifier{&ue_mng}; dummy_du_connection_notifier du_conn_notifier; dummy_f1ap_pdu_notifier f1ap_pdu_notifier; - dummy_rrc_ue_ngap_adapter rrc_ue_ngap_notifier; dummy_rrc_ue_cu_cp_adapter rrc_ue_cu_cp_notifier; dummy_rrc_du_cu_cp_adapter rrc_du_cu_cp_notifier; std::unique_ptr cu_cp_event_handler; From ae750af68677c2aa9028500e72bcd401f0fd49ed Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 3 Sep 2024 16:08:52 +0200 Subject: [PATCH 032/174] cu_cp,rrc: remove unused values --- include/srsran/cu_cp/cu_cp_types.h | 2 -- lib/rrc/ue/procedures/rrc_setup_procedure.cpp | 1 - lib/rrc/ue/rrc_ue_message_handlers.cpp | 1 - 3 files changed, 4 deletions(-) diff --git a/include/srsran/cu_cp/cu_cp_types.h b/include/srsran/cu_cp/cu_cp_types.h index da209981a6..764c344943 100644 --- a/include/srsran/cu_cp/cu_cp_types.h +++ b/include/srsran/cu_cp/cu_cp_types.h @@ -189,7 +189,6 @@ struct cu_cp_five_g_s_tmsi { struct cu_cp_initial_ue_message { ue_index_t ue_index = ue_index_t::invalid; - plmn_identity plmn = plmn_identity::test_value(); byte_buffer nas_pdu; establishment_cause_t establishment_cause; cu_cp_user_location_info_nr user_location_info; @@ -199,7 +198,6 @@ struct cu_cp_initial_ue_message { struct cu_cp_ul_nas_transport { ue_index_t ue_index = ue_index_t::invalid; - plmn_identity plmn = plmn_identity::test_value(); byte_buffer nas_pdu; cu_cp_user_location_info_nr user_location_info; }; diff --git a/lib/rrc/ue/procedures/rrc_setup_procedure.cpp b/lib/rrc/ue/procedures/rrc_setup_procedure.cpp index f692629c0a..561897aed7 100644 --- a/lib/rrc/ue/procedures/rrc_setup_procedure.cpp +++ b/lib/rrc/ue/procedures/rrc_setup_procedure.cpp @@ -101,7 +101,6 @@ void rrc_setup_procedure::send_initial_ue_msg(const asn1::rrc_nr::rrc_setup_comp const auto& rrc_setup_complete = rrc_setup_complete_msg.crit_exts.rrc_setup_complete(); init_ue_msg.ue_index = context.ue_index; - init_ue_msg.plmn = context.cell.cgi.plmn_id; init_ue_msg.nas_pdu = rrc_setup_complete.ded_nas_msg.copy(); init_ue_msg.establishment_cause = static_cast(context.connection_cause.value); init_ue_msg.user_location_info.nr_cgi = context.cell.cgi; diff --git a/lib/rrc/ue/rrc_ue_message_handlers.cpp b/lib/rrc/ue/rrc_ue_message_handlers.cpp index d4f2dc0f60..6400c634ac 100644 --- a/lib/rrc/ue/rrc_ue_message_handlers.cpp +++ b/lib/rrc/ue/rrc_ue_message_handlers.cpp @@ -217,7 +217,6 @@ void rrc_ue_impl::handle_ul_info_transfer(const ul_info_transfer_ies_s& ul_info_ { cu_cp_ul_nas_transport ul_nas_msg = {}; ul_nas_msg.ue_index = context.ue_index; - ul_nas_msg.plmn = context.cell.cgi.plmn_id; ul_nas_msg.nas_pdu = ul_info_transfer.ded_nas_msg.copy(); ul_nas_msg.user_location_info.nr_cgi = context.cell.cgi; ul_nas_msg.user_location_info.tai.plmn_id = context.cell.cgi.plmn_id; From 7d9d25aa325270da4d11712ca83abe05a9cfd38b Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 13 Sep 2024 11:05:03 +0200 Subject: [PATCH 033/174] ci: update retina version --- .gitlab/ci/e2e/.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/e2e/.env b/.gitlab/ci/e2e/.env index 96f6d707ed..ca56bf5e7c 100644 --- a/.gitlab/ci/e2e/.env +++ b/.gitlab/ci/e2e/.env @@ -1,6 +1,6 @@ SRSGNB_REGISTRY_URI=registry.gitlab.com/softwareradiosystems/srsgnb RETINA_REGISTRY_PREFIX=registry.gitlab.com/softwareradiosystems/ci/retina -RETINA_VERSION=0.52.13 +RETINA_VERSION=0.52.17 UBUNTU_VERSION=24.04 AMARISOFT_VERSION=2023-09-08 SRSUE_VERSION=23.11 From a13afabd25e5cf44562719a1dcdfd6e8c4ca1f99 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 13 Sep 2024 11:05:26 +0200 Subject: [PATCH 034/174] ci: update test mode --- tests/e2e/tests/test_mode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/test_mode.py b/tests/e2e/tests/test_mode.py index 85e854108b..71089a5641 100644 --- a/tests/e2e/tests/test_mode.py +++ b/tests/e2e/tests/test_mode.py @@ -233,7 +233,7 @@ def _test_ru( fivegc_definition=FiveGCDefinition(amf_ip=gnb_def.zmq_ip, amf_port=38412), start_info=StartInfo( timeout=gnb_startup_timeout, - post_commands=("amf --no_core 1",), + post_commands=("cu_cp amf --no_core 1",), ), ) ) From efdcd1d351ad961389d15d4090da42c1f7de1e9d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 30 Jul 2024 10:58:05 +0100 Subject: [PATCH 035/174] cu_cp: added basic plugin loader functionality --- include/srsran/ngap/ngap_handover.h | 4 +++ lib/cu_cp/cu_cp_impl.cpp | 41 +++++++++++++++++++++++++++++ lib/cu_cp/cu_cp_impl.h | 4 +++ 3 files changed, 49 insertions(+) diff --git a/include/srsran/ngap/ngap_handover.h b/include/srsran/ngap/ngap_handover.h index f2c01cd522..481d9757b0 100644 --- a/include/srsran/ngap/ngap_handover.h +++ b/include/srsran/ngap/ngap_handover.h @@ -13,6 +13,7 @@ #include "ngap_types.h" #include "srsran/cu_cp/cu_cp_types.h" #include "srsran/security/security.h" +#include "srsran/support/async/async_task.h" namespace srsran { namespace srs_cu_cp { @@ -153,5 +154,8 @@ struct ngap_handover_resource_allocation_response { std::optional crit_diagnostics; }; +// Function pointer prototype for starting handover from plugin +using start_ngap_handover_preparation_procedure_func = async_task (*)(); + } // namespace srs_cu_cp } // namespace srsran diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 6fe115b150..b8bafc80cc 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -27,6 +27,7 @@ #include "srsran/f1ap/cu_cp/f1ap_cu.h" #include "srsran/rrc/rrc_du.h" #include +#include #include #include @@ -67,6 +68,11 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : { assert_cu_cp_configuration_valid(cfg); + if (not load_plugins()) { + logger.error("Could not load CU-CP plugins"); + report_fatal_error("Could not load CU-CP plugins"); + } + // connect event notifiers to layers ngap_cu_cp_ev_notifier.connect_cu_cp(*this, paging_handler); mobility_manager_ev_notifier.connect_cu_cp(get_cu_cp_mobility_manager_handler()); @@ -131,6 +137,41 @@ void cu_cp_impl::stop() logger.info("CU-CP stopped successfully."); } +bool cu_cp_impl::load_plugins() +{ + char* err = nullptr; + std::string plugin_name = "libsrsran_plugin_ng_handover.so"; + + void* dl_handle = ::dlopen(plugin_name.c_str(), RTLD_NOW + RTLD_DEEPBIND + RTLD_GLOBAL); + if (dl_handle == nullptr) { + err = ::dlerror(); + if (err != nullptr) { + fmt::print("Failed to load HO plugin {}: {}\n", plugin_name, err); + } else { + fmt::print("Failed to load HO plugin {}\n", plugin_name); + } + return false; + } + fmt::print("loaded plugin\n"); + + // Load symbol. + start_ho_prep_func = reinterpret_cast( + ::dlsym(dl_handle, "_ZN6srsran9srs_cu_cp15testing_funtionERNS_25fifo_async_task_schedulerE")); + + // Handle an error loading the symbol. + if (start_ho_prep_func == nullptr) { + err = ::dlerror(); + if (err != nullptr) { + fmt::print("Error loading symbol {}: {}\n", "testing_function", err); + } else { + fmt::print("Error loading symbol {}:\n", "testing_function"); + } + return false; + } + fmt::print("loaded start function\n"); + return true; +} + ngap_message_handler* cu_cp_impl::get_ngap_message_handler(const plmn_identity& plmn) { return ngap_db.find_ngap(plmn); diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index 3d1e1c1a0c..8a77f3f408 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -202,6 +202,10 @@ class cu_cp_impl final : public cu_cp, unique_timer statistics_report_timer; std::atomic stopped{false}; + + // Plug-ins + [[nodiscard]] bool load_plugins(); + start_ngap_handover_preparation_procedure_func start_ho_prep_func = nullptr; }; } // namespace srs_cu_cp From 5da567a0bcb9d36f7d373166273769da27d29e9c Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 9 Sep 2024 15:56:02 +0100 Subject: [PATCH 036/174] ngap: start to call ng handover preperation function from plugin --- include/srsran/ngap/ngap_factory.h | 11 +++--- lib/cu_cp/cu_cp_impl.cpp | 26 +++++++------ lib/cu_cp/cu_cp_impl.h | 2 +- lib/cu_cp/ngap_repository.cpp | 1 + lib/cu_cp/ngap_repository.h | 9 +++-- lib/ngap/ngap_factory.cpp | 15 +++++--- lib/ngap/ngap_impl.cpp | 38 +++++++++---------- lib/ngap/ngap_impl.h | 14 ++++--- .../ngap/ngap_integration_test.cpp | 2 +- tests/unittests/ngap/ngap_test_helpers.cpp | 2 +- 10 files changed, 66 insertions(+), 54 deletions(-) diff --git a/include/srsran/ngap/ngap_factory.h b/include/srsran/ngap/ngap_factory.h index 56b1a62cab..aaebd231c0 100644 --- a/include/srsran/ngap/ngap_factory.h +++ b/include/srsran/ngap/ngap_factory.h @@ -22,11 +22,12 @@ namespace srs_cu_cp { class n2_connection_client; /// Creates an instance of an NGAP interface, notifying outgoing packets on the specified listener object. -std::unique_ptr create_ngap(const ngap_configuration& ngap_cfg_, - ngap_cu_cp_notifier& cu_cp_notifier_, - n2_connection_client& n2_gateway_handler_, - timer_manager& timers_, - task_executor& ctrl_exec_); +std::unique_ptr create_ngap(const ngap_configuration& ngap_cfg_, + ngap_cu_cp_notifier& cu_cp_notifier_, + start_ngap_handover_preparation_procedure_func start_ho_prep_func, + n2_connection_client& n2_gateway_handler_, + timer_manager& timers_, + task_executor& ctrl_exec_); } // namespace srs_cu_cp diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index b8bafc80cc..00eab23a62 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -62,7 +62,6 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : srslog::fetch_basic_logger("CU-CP")}), cu_up_db(cu_up_repository_config{cfg, e1ap_ev_notifier, srslog::fetch_basic_logger("CU-CP")}), paging_handler(du_db), - ngap_db(ngap_repository_config{cfg, get_cu_cp_ngap_handler(), paging_handler, srslog::fetch_basic_logger("CU-CP")}), metrics_hdlr( std::make_unique(*cfg.services.cu_cp_executor, *cfg.services.timers, ue_mng, du_db)) { @@ -79,12 +78,15 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : e1ap_ev_notifier.connect_cu_cp(get_cu_cp_e1ap_handler()); rrc_du_cu_cp_notifier.connect_cu_cp(get_cu_cp_measurement_config_handler()); + ngap_db = std::make_unique(ngap_repository_config{ + cfg, get_cu_cp_ngap_handler(), paging_handler, start_ho_prep_func, srslog::fetch_basic_logger("CU-CP")}); + controller = std::make_unique( - cfg, common_task_sched, ngap_db, cu_up_db, du_db, *cfg.services.cu_cp_executor); + cfg, common_task_sched, *ngap_db, cu_up_db, du_db, *cfg.services.cu_cp_executor); conn_notifier.connect_node_connection_handler(*controller); mobility_mng = create_mobility_manager( - cfg.mobility.mobility_manager_config, mobility_manager_ev_notifier, ngap_db, du_db, ue_mng); + cfg.mobility.mobility_manager_config, mobility_manager_ev_notifier, *ngap_db, du_db, ue_mng); cell_meas_ev_notifier.connect_mobility_manager(*mobility_mng); // Start statistics report timer @@ -174,12 +176,12 @@ bool cu_cp_impl::load_plugins() ngap_message_handler* cu_cp_impl::get_ngap_message_handler(const plmn_identity& plmn) { - return ngap_db.find_ngap(plmn); + return ngap_db->find_ngap(plmn); }; bool cu_cp_impl::amfs_are_connected() { - for (const auto& [amf_index, ngap] : ngap_db.get_ngaps()) { + for (const auto& [amf_index, ngap] : ngap_db->get_ngaps()) { if (not controller->amf_connection_handler().is_amf_connected(amf_index)) { return false; } @@ -331,7 +333,7 @@ async_task cu_cp_impl::handle_ue_context_transfer(ue_index_t ue_index, ue_ } } - auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + auto* ngap = ngap_db->find_ngap(ue->get_ue_context().plmn); if (ngap == nullptr) { logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); return false; @@ -408,7 +410,7 @@ void cu_cp_impl::handle_handover_ue_context_push(ue_index_t source_ue_index, ue_ auto* ue = ue_mng.find_ue(target_ue_index); - auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + auto* ngap = ngap_db->find_ngap(ue->get_ue_context().plmn); if (ngap == nullptr) { logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); return; @@ -433,7 +435,7 @@ async_task cu_cp_impl::handle_ue_context_release(const cu_cp_ue_context_re }); } - auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + auto* ngap = ngap_db->find_ngap(ue->get_ue_context().plmn); if (ngap == nullptr) { logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); return launch_async([](coro_context>& ctx) { @@ -464,7 +466,7 @@ cu_cp_impl::handle_new_initial_context_setup_request(const ngap_init_context_set rrc_ue_interface* rrc_ue = ue->get_rrc_ue(); srsran_assert(rrc_ue != nullptr, "ue={}: Could not find RRC UE", request.ue_index); - auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + auto* ngap = ngap_db->find_ngap(ue->get_ue_context().plmn); if (ngap == nullptr) { logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); return launch_async( @@ -695,7 +697,7 @@ async_task cu_cp_impl::handle_ue_removal_request(ue_index_t ue_index) e1ap_removal_handler = &cu_up_db.find_cu_up_processor(cu_up_index)->get_e1ap_bearer_context_removal_handler(); } - auto* ngap = ngap_db.find_ngap(ue->get_ue_context().plmn); + auto* ngap = ngap_db->find_ngap(ue->get_ue_context().plmn); if (ngap == nullptr) { logger.warning("NGAP not found for PLMN={}", ue->get_ue_context().plmn); return launch_async([](coro_context>& ctx) { @@ -739,7 +741,7 @@ void cu_cp_impl::handle_rrc_ue_creation(ue_index_t ue_index, rrc_ue_interface& r ue_mng.get_ngap_rrc_ue_adapter(ue_index).connect_rrc_ue(rrc_ue.get_rrc_ngap_message_handler()); // Connect NGAP to RRC UE to NGAP adapter - ue_mng.get_rrc_ue_ngap_adapter(ue_index).connect_ngap(ngap_db.find_ngap(ue->get_ue_context().plmn)); + ue_mng.get_rrc_ue_ngap_adapter(ue_index).connect_ngap(ngap_db->find_ngap(ue->get_ue_context().plmn)); // Connect cu-cp to rrc ue adapters ue_mng.get_rrc_ue_cu_cp_adapter(ue_index).connect_cu_cp(get_cu_cp_rrc_ue_interface(), @@ -787,7 +789,7 @@ void cu_cp_impl::on_statistics_report_timer_expired() unsigned nof_rrc_ues = du_db.get_nof_rrc_ues(); // Get number of NGAP UEs - unsigned nof_ngap_ues = ngap_db.get_nof_ngap_ues(); + unsigned nof_ngap_ues = ngap_db->get_nof_ngap_ues(); // Get number of E1AP UEs unsigned nof_e1ap_ues = cu_up_db.get_nof_e1ap_ues(); diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index 8a77f3f408..e3edb80e61 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -192,7 +192,7 @@ class cu_cp_impl final : public cu_cp, paging_message_handler paging_handler; // AMF connections beeing managed by the CU-CP. - ngap_repository ngap_db; + std::unique_ptr ngap_db; // Handler of the CU-CP connections to other remote nodes (e.g. AMF, CU-UPs, DUs). std::unique_ptr controller; diff --git a/lib/cu_cp/ngap_repository.cpp b/lib/cu_cp/ngap_repository.cpp index 70c9320a4f..c63c8774de 100644 --- a/lib/cu_cp/ngap_repository.cpp +++ b/lib/cu_cp/ngap_repository.cpp @@ -39,6 +39,7 @@ ngap_interface* ngap_repository::add_ngap(amf_index_t amf_index, const cu_cp_con cfg.cu_cp.ue.pdu_session_setup_timeout}; std::unique_ptr ngap_entity = create_ngap(ngap_cfg, ngap_ctxt.ngap_to_cu_cp_notifier, + cfg.start_ho_func, *config.n2_gw, *cfg.cu_cp.services.timers, *cfg.cu_cp.services.cu_cp_executor); diff --git a/lib/cu_cp/ngap_repository.h b/lib/cu_cp/ngap_repository.h index 8e208e950c..00452886b5 100644 --- a/lib/cu_cp/ngap_repository.h +++ b/lib/cu_cp/ngap_repository.h @@ -23,10 +23,11 @@ namespace srs_cu_cp { struct cu_cp_configuration; struct ngap_repository_config { - const cu_cp_configuration& cu_cp; - cu_cp_ngap_handler& cu_cp_notifier; - paging_message_handler& paging_handler; - srslog::basic_logger& logger; + const cu_cp_configuration& cu_cp; + cu_cp_ngap_handler& cu_cp_notifier; + paging_message_handler& paging_handler; + start_ngap_handover_preparation_procedure_func start_ho_func; + srslog::basic_logger& logger; }; class ngap_repository diff --git a/lib/ngap/ngap_factory.cpp b/lib/ngap/ngap_factory.cpp index 11295eab97..cef5a917e8 100644 --- a/lib/ngap/ngap_factory.cpp +++ b/lib/ngap/ngap_factory.cpp @@ -16,12 +16,15 @@ using namespace srsran; using namespace srs_cu_cp; -std::unique_ptr srsran::srs_cu_cp::create_ngap(const ngap_configuration& ngap_cfg_, - ngap_cu_cp_notifier& cu_cp_notifier_, - n2_connection_client& n2_gateway_handler_, - timer_manager& timers_, - task_executor& ctrl_exec_) +std::unique_ptr +srsran::srs_cu_cp::create_ngap(const ngap_configuration& ngap_cfg_, + ngap_cu_cp_notifier& cu_cp_notifier_, + start_ngap_handover_preparation_procedure_func start_ho_prep_func, + n2_connection_client& n2_gateway_handler_, + timer_manager& timers_, + task_executor& ctrl_exec_) { - auto ngap = std::make_unique(ngap_cfg_, cu_cp_notifier_, n2_gateway_handler_, timers_, ctrl_exec_); + auto ngap = std::make_unique( + ngap_cfg_, cu_cp_notifier_, start_ho_prep_func, n2_gateway_handler_, timers_, ctrl_exec_); return ngap; } diff --git a/lib/ngap/ngap_impl.cpp b/lib/ngap/ngap_impl.cpp index cab14b8c40..1c7a2fcd22 100644 --- a/lib/ngap/ngap_impl.cpp +++ b/lib/ngap/ngap_impl.cpp @@ -33,18 +33,20 @@ using namespace srsran; using namespace asn1::ngap; using namespace srs_cu_cp; -ngap_impl::ngap_impl(const ngap_configuration& ngap_cfg_, - ngap_cu_cp_notifier& cu_cp_notifier_, - n2_connection_client& n2_gateway, - timer_manager& timers_, - task_executor& ctrl_exec_) : +ngap_impl::ngap_impl(const ngap_configuration& ngap_cfg_, + ngap_cu_cp_notifier& cu_cp_notifier_, + start_ngap_handover_preparation_procedure_func start_ho_prep_func_, + n2_connection_client& n2_gateway, + timer_manager& timers_, + task_executor& ctrl_exec_) : logger(srslog::fetch_basic_logger("NGAP")), ue_ctxt_list(logger), cu_cp_notifier(cu_cp_notifier_), timers(timers_), ctrl_exec(ctrl_exec_), ev_mng(timer_factory{timers, ctrl_exec}), - conn_handler(n2_gateway, *this, cu_cp_notifier, ctrl_exec) + conn_handler(n2_gateway, *this, cu_cp_notifier, ctrl_exec), + start_ho_prep_func(start_ho_prep_func_) { context.gnb_id = ngap_cfg_.gnb_id; context.ran_node_name = ngap_cfg_.ran_node_name; @@ -919,12 +921,18 @@ async_task ngap_impl::handle_ue_context_release_request(const cu_cp_ue_con async_task ngap_impl::handle_handover_preparation_request(const ngap_handover_preparation_request& msg) { + auto err_function = [](coro_context>& ctx) { + CORO_BEGIN(ctx); + CORO_RETURN(ngap_handover_preparation_response{false}); + }; + + if (start_ho_prep_func == nullptr) { + logger.error("ue={}: Dropping HandoverPreparationRequest. NG handover plugin is not loaded", msg.ue_index); + return launch_async(std::move(err_function)); + } if (!ue_ctxt_list.contains(msg.ue_index)) { logger.warning("ue={}: Dropping HandoverPreparationRequest. UE context does not exist", msg.ue_index); - return launch_async([](coro_context>& ctx) { - CORO_BEGIN(ctx); - CORO_RETURN(ngap_handover_preparation_response{false}); - }); + return launch_async(std::move(err_function)); } ngap_ue_context& ue_ctxt = ue_ctxt_list[msg.ue_index]; @@ -938,15 +946,7 @@ ngap_impl::handle_handover_preparation_request(const ngap_handover_preparation_r ue_ctxt.logger.log_info("Starting HO preparation"); - return launch_async(msg, - ue_ctxt.serving_guami.plmn, - ue_ctxt.ue_ids, - *tx_pdu_notifier, - ue->get_ngap_rrc_ue_notifier(), - cu_cp_notifier, - ev_mng, - timer_factory{timers, ctrl_exec}, - ue_ctxt.logger); + return (*start_ho_prep_func)(); } void ngap_impl::handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t ue_index, diff --git a/lib/ngap/ngap_impl.h b/lib/ngap/ngap_impl.h index 7182708907..6bbb0dfef3 100644 --- a/lib/ngap/ngap_impl.h +++ b/lib/ngap/ngap_impl.h @@ -29,11 +29,12 @@ namespace srs_cu_cp { class ngap_impl final : public ngap_interface { public: - ngap_impl(const ngap_configuration& ngap_cfg_, - ngap_cu_cp_notifier& cu_cp_notifier_, - n2_connection_client& n2_gateway, - timer_manager& timers_, - task_executor& ctrl_exec_); + ngap_impl(const ngap_configuration& ngap_cfg_, + ngap_cu_cp_notifier& cu_cp_notifier_, + start_ngap_handover_preparation_procedure_func start_ho_prep_func_, + n2_connection_client& n2_gateway, + timer_manager& timers_, + task_executor& ctrl_exec_); ~ngap_impl(); bool @@ -176,6 +177,9 @@ class ngap_impl final : public ngap_interface ngap_connection_handler conn_handler; std::unique_ptr tx_pdu_notifier; + + // Plugins + start_ngap_handover_preparation_procedure_func start_ho_prep_func = nullptr; }; } // namespace srs_cu_cp diff --git a/tests/integrationtests/ngap/ngap_integration_test.cpp b/tests/integrationtests/ngap/ngap_integration_test.cpp index 0ddcfcfd64..0d83a4c590 100644 --- a/tests/integrationtests/ngap/ngap_integration_test.cpp +++ b/tests/integrationtests/ngap/ngap_integration_test.cpp @@ -137,7 +137,7 @@ class ngap_integration_test : public ::testing::Test srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::debug); srslog::init(); - ngap = create_ngap(cfg, cu_cp_notifier, *cu_cp_cfg.ngaps.front().n2_gw, timers, ctrl_worker); + ngap = create_ngap(cfg, cu_cp_notifier, nullptr, *cu_cp_cfg.ngaps.front().n2_gw, timers, ctrl_worker); } timer_manager timers; diff --git a/tests/unittests/ngap/ngap_test_helpers.cpp b/tests/unittests/ngap/ngap_test_helpers.cpp index cd0392c967..9122ad4c32 100644 --- a/tests/unittests/ngap/ngap_test_helpers.cpp +++ b/tests/unittests/ngap/ngap_test_helpers.cpp @@ -40,7 +40,7 @@ ngap_test::ngap_test() : ngap_cfg.ran_node_name = cu_cp_cfg.node.ran_node_name; ngap_cfg.supported_tas = cu_cp_cfg.ngaps.front().supported_tas; ngap_cfg.pdu_session_setup_timeout = cu_cp_cfg.ue.pdu_session_setup_timeout; - ngap = create_ngap(ngap_cfg, cu_cp_notifier, *cu_cp_cfg.ngaps.front().n2_gw, timers, ctrl_worker); + ngap = create_ngap(ngap_cfg, cu_cp_notifier, nullptr, *cu_cp_cfg.ngaps.front().n2_gw, timers, ctrl_worker); cu_cp_notifier.connect_ngap(ngap->get_ngap_ue_context_removal_handler()); From 6310199d272ba32f6c5c78229bd046ac011c04a9 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 9 Sep 2024 17:18:41 +0100 Subject: [PATCH 037/174] cu_cp: added cli option to enable/disable loading plugins --- apps/units/cu_cp/cu_cp_config_translators.cpp | 6 ++++++ apps/units/cu_cp/cu_cp_unit_config.h | 2 ++ apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp | 5 +++++ include/srsran/cu_cp/cu_cp_configuration.h | 2 ++ include/srsran/cu_cp/mobility_manager_config.h | 1 + lib/cu_cp/cu_cp_impl.cpp | 2 +- lib/cu_cp/mobility_manager/mobility_manager_impl.cpp | 5 +++++ 7 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/units/cu_cp/cu_cp_config_translators.cpp b/apps/units/cu_cp/cu_cp_config_translators.cpp index c1f48836ad..f1a1629968 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.cpp +++ b/apps/units/cu_cp/cu_cp_config_translators.cpp @@ -373,17 +373,23 @@ srs_cu_cp::cu_cp_configuration srsran::generate_cu_cp_config(const cu_cp_unit_co cu_cfg.security_config.confidentiality_protection); } + // Timers out_cfg.ue.inactivity_timer = std::chrono::seconds{cu_cfg.inactivity_timer}; out_cfg.ue.pdu_session_setup_timeout = std::chrono::seconds{cu_cfg.pdu_session_setup_timeout}; out_cfg.metrics.statistics_report_period = std::chrono::seconds{cu_cfg.metrics.cu_cp_statistics_report_period}; + // Mobility out_cfg.mobility.mobility_manager_config.trigger_handover_from_measurements = cu_cfg.mobility_config.trigger_handover_from_measurements; + out_cfg.mobility.mobility_manager_config.enable_ng_handover = cu_cfg.load_plugins; // F1AP-CU config. out_cfg.f1ap.proc_timeout = std::chrono::milliseconds{cu_cfg.f1ap_config.procedure_timeout}; out_cfg.f1ap.json_log_enabled = cu_cfg.loggers.f1ap_json_enabled; + // Plugins + out_cfg.load_plugins = cu_cfg.load_plugins; + // Convert appconfig's cell list into cell manager type. for (const auto& app_cfg_item : cu_cfg.mobility_config.cells) { nr_cell_identity nci = nr_cell_identity::create(app_cfg_item.nr_cell_id).value(); diff --git a/apps/units/cu_cp/cu_cp_unit_config.h b/apps/units/cu_cp/cu_cp_unit_config.h index 28d25f0a61..0b2a5f748c 100644 --- a/apps/units/cu_cp/cu_cp_unit_config.h +++ b/apps/units/cu_cp/cu_cp_unit_config.h @@ -262,6 +262,8 @@ struct cu_cp_unit_config { uint64_t max_nof_ues = 8192; /// Inactivity timer in seconds. int inactivity_timer = 120; + /// Load enterprise plugins. + bool load_plugins = false; /// PDU session setup timeout in seconds (must be larger than T310). unsigned pdu_session_setup_timeout = 3; /// Loggers configuration. diff --git a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp index 844f89e2f8..09727f86ca 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp +++ b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp @@ -374,6 +374,11 @@ static void configure_cli11_cu_cp_args(CLI::App& app, cu_cp_unit_config& cu_cp_p "seconds. The timeout must be larger than T310. If the value is reached, the UE will be released") ->capture_default_str(); + add_option(app, + "--load_plugins", + cu_cp_params.load_plugins, + "Attempt to load plugin library to enable srsRAN_Enterprise features"); + CLI::App* amf_subcmd = app.add_subcommand("amf", "AMF configuration"); configure_cli11_amf_args(*amf_subcmd, cu_cp_params.amf_config); diff --git a/include/srsran/cu_cp/cu_cp_configuration.h b/include/srsran/cu_cp/cu_cp_configuration.h index 86f2bc6801..dd16ea4fbc 100644 --- a/include/srsran/cu_cp/cu_cp_configuration.h +++ b/include/srsran/cu_cp/cu_cp_configuration.h @@ -114,6 +114,8 @@ struct cu_cp_configuration { mobility_configuration mobility; /// Parameters related with CU-CP metrics. metrics_params metrics; + /// Plugins parameters + bool load_plugins; /// Timers, executors, and other services used by the CU-CP. service_params services; }; diff --git a/include/srsran/cu_cp/mobility_manager_config.h b/include/srsran/cu_cp/mobility_manager_config.h index f7b76e39f1..40c5d12f26 100644 --- a/include/srsran/cu_cp/mobility_manager_config.h +++ b/include/srsran/cu_cp/mobility_manager_config.h @@ -17,6 +17,7 @@ namespace srs_cu_cp { /// \brief Mobility manager configuration. struct mobility_manager_cfg { bool trigger_handover_from_measurements = false; ///< Set to true to trigger HO when neighbor becomes stronger. + bool enable_ng_handover = false; ///< Set to true if plugins are loaded to enable NG handover. }; } // namespace srs_cu_cp diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 00eab23a62..cb9f577186 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -67,7 +67,7 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : { assert_cu_cp_configuration_valid(cfg); - if (not load_plugins()) { + if (cfg.load_plugins && not load_plugins()) { logger.error("Could not load CU-CP plugins"); report_fatal_error("Could not load CU-CP plugins"); } diff --git a/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp b/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp index 5d11321fd0..9f5ac201dc 100644 --- a/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp +++ b/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp @@ -139,6 +139,11 @@ void mobility_manager::handle_inter_cu_handover(ue_index_t source_ue_index gnb_id_t target_gnb_id, nr_cell_identity target_nci) { + if (not cfg.enable_ng_handover) { + logger.error("ue={}: trying to use NG handover without HO plugin loaded.", source_ue_index); + return; + } + cu_cp_ue* u = ue_mng.find_du_ue(source_ue_index); if (u == nullptr) { logger.error("ue={}: Couldn't find UE", source_ue_index); From 55db10eb5658d0c2a0464fe34e4498ca4d960140 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 9 Sep 2024 17:41:54 +0100 Subject: [PATCH 038/174] cu_cp,ngap: remove unit tests for NG handover --- tests/unittests/cu_cp/CMakeLists.txt | 1 - .../cu_cp/cu_cp_inter_cu_handover_test.cpp | 273 ------------------ tests/unittests/ngap/ngap_handover_test.cpp | 40 --- 3 files changed, 314 deletions(-) delete mode 100644 tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp diff --git a/tests/unittests/cu_cp/CMakeLists.txt b/tests/unittests/cu_cp/CMakeLists.txt index 07fad9b779..ed36eb2976 100644 --- a/tests/unittests/cu_cp/CMakeLists.txt +++ b/tests/unittests/cu_cp/CMakeLists.txt @@ -42,7 +42,6 @@ add_executable(cu_cp_test cu_cp_paging_test.cpp cu_cp_inactivity_notification_test.cpp cu_cp_inter_du_handover_test.cpp - cu_cp_inter_cu_handover_test.cpp ) set_target_properties(cu_cp_test PROPERTIES UNITY_BUILD ON) target_link_libraries(cu_cp_test diff --git a/tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp b/tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp deleted file mode 100644 index af434fa477..0000000000 --- a/tests/unittests/cu_cp/cu_cp_inter_cu_handover_test.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * - * Copyright 2021-2024 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#include "cu_cp_test_environment.h" -#include "tests/test_doubles/e1ap/e1ap_test_message_validators.h" -#include "tests/test_doubles/f1ap/f1ap_test_message_validators.h" -#include "tests/test_doubles/ngap/ngap_test_message_validators.h" -#include "tests/test_doubles/rrc/rrc_test_message_validators.h" -#include "tests/unittests/cu_cp/test_helpers.h" -#include "tests/unittests/e1ap/common/e1ap_cu_cp_test_messages.h" -#include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h" -#include "tests/unittests/ngap/ngap_test_messages.h" -#include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" -#include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" -#include "srsran/ngap/ngap_message.h" -#include "srsran/support/test_utils.h" -#include - -using namespace srsran; -using namespace srs_cu_cp; - -class cu_cp_inter_cu_handover_test : public cu_cp_test_environment, public ::testing::Test -{ -public: - cu_cp_inter_cu_handover_test() : cu_cp_test_environment(cu_cp_test_env_params{}) - { - // Run NG setup to completion. - run_ng_setup(); - - // Setup DU. - std::optional ret = connect_new_du(); - EXPECT_TRUE(ret.has_value()); - du_idx = ret.value(); - EXPECT_TRUE(this->run_f1_setup(du_idx)); - - // Setup CU-UP. - ret = connect_new_cu_up(); - EXPECT_TRUE(ret.has_value()); - cu_up_idx = ret.value(); - EXPECT_TRUE(this->run_e1_setup(cu_up_idx)); - } - - [[nodiscard]] bool attach_ue() - { - if (!cu_cp_test_environment::attach_ue( - du_idx, cu_up_idx, du_ue_id, crnti, amf_ue_id, cu_up_e1ap_id, psi, drb_id_t::drb1, qfi)) { - return false; - } - ue_ctx = this->find_ue_context(du_idx, du_ue_id); - - return ue_ctx != nullptr; - } - - [[nodiscard]] bool send_handover_request_and_await_bearer_context_setup_request() - { - report_fatal_error_if_not(not this->get_amf().try_pop_rx_pdu(ngap_pdu), - "there are still NGAP messages to pop from AMF"); - report_fatal_error_if_not(not this->get_du(du_idx).try_pop_dl_pdu(f1ap_pdu), - "there are still F1AP DL messages to pop from DU"); - report_fatal_error_if_not(not this->get_cu_up(cu_up_idx).try_pop_rx_pdu(e1ap_pdu), - "there are still E1AP messages to pop from CU-UP"); - - // Inject Handover Request and wait for Bearer Context Setup Request - get_amf().push_tx_pdu(generate_valid_handover_request(amf_ue_id)); - report_fatal_error_if_not(this->wait_for_e1ap_tx_pdu(cu_up_idx, e1ap_pdu), - "Failed to receive Bearer Context Setup Request"); - report_fatal_error_if_not(test_helpers::is_valid_bearer_context_setup_request(e1ap_pdu), - "Invalid Bearer Context Setup Request"); - - cu_cp_e1ap_id = - int_to_gnb_cu_cp_ue_e1ap_id(e1ap_pdu.pdu.init_msg().value.bearer_context_setup_request()->gnb_cu_cp_ue_e1ap_id); - return true; - } - - [[nodiscard]] bool send_bearer_context_setup_response_and_await_ue_context_setup_request() - { - // Inject Bearer Context Setup Response and wait for UE Context Setup Request - get_cu_up(cu_up_idx).push_tx_pdu(generate_bearer_context_setup_response(cu_cp_e1ap_id, cu_up_e1ap_id)); - report_fatal_error_if_not(this->wait_for_f1ap_tx_pdu(du_idx, f1ap_pdu), - "Failed to receive UE Context Setup Request"); - report_fatal_error_if_not(test_helpers::is_valid_ue_context_setup_request(f1ap_pdu), - "Invalid UE Context Setup Request"); - - cu_ue_id = int_to_gnb_cu_ue_f1ap_id(f1ap_pdu.pdu.init_msg().value.ue_context_setup_request()->gnb_cu_ue_f1ap_id); - return true; - } - - [[nodiscard]] bool send_ue_context_setup_response_and_await_bearer_context_modification_request() - { - // Inject UE Context Setup Response and wait for Bearer Context Modification Request - get_du(du_idx).push_ul_pdu(generate_ue_context_setup_response(cu_ue_id, du_ue_id, crnti)); - report_fatal_error_if_not(this->wait_for_e1ap_tx_pdu(cu_up_idx, e1ap_pdu), - "Failed to receive Bearer Context Modification Request"); - report_fatal_error_if_not(test_helpers::is_valid_bearer_context_modification_request(e1ap_pdu), - "Invalid Bearer Context Modification Request"); - return true; - } - - [[nodiscard]] bool send_bearer_context_modification_response_and_await_handover_request_ack() - { - // Inject Bearer Context Modification Response and wait for Handover Request Ack - get_cu_up(cu_up_idx).push_tx_pdu(generate_bearer_context_modification_response(cu_cp_e1ap_id, cu_up_e1ap_id)); - report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu), "Failed to receive Handover Request Ack"); - report_fatal_error_if_not(test_helpers::is_valid_handover_request_ack(ngap_pdu), "Invalid Handover Request Ack"); - return true; - } - - [[nodiscard]] bool send_rrc_reconfiguration_complete_and_await_handover_notify() - { - // Inject UL RRC Message (containing RRC Reconfiguration Complete) and wait for Handover Notify - get_du(du_idx).push_ul_pdu(generate_ul_rrc_message_transfer( - cu_ue_id, du_ue_id, srb_id_t::srb1, make_byte_buffer("800008004e17dae3").value())); - report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu), "Failed to receive Handover Notify"); - report_fatal_error_if_not(test_helpers::is_valid_handover_notify(ngap_pdu), "Invalid Handover Notify"); - return true; - } - - [[nodiscard]] bool send_rrc_measurement_report_and_await_handover_required() - { - // Inject UL RRC Message (containing RRC Measurement Report) and wait for Handover Required - get_du(du_idx).push_ul_pdu( - generate_ul_rrc_message_transfer(ue_ctx->cu_ue_id.value(), - ue_ctx->du_ue_id.value(), - srb_id_t::srb1, - make_byte_buffer("000800410004015f741fe0804bf183fcaa6e9699").value())); - report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu), "Failed to receive Handover Required"); - report_fatal_error_if_not(test_helpers::is_valid_handover_required(ngap_pdu), "Invalid Handover Required"); - return true; - } - - [[nodiscard]] bool send_handover_preparation_failure() - { - // Inject Handover Preparation Failure - get_amf().push_tx_pdu(generate_handover_preparation_failure(ue_ctx->amf_ue_id.value(), ue_ctx->ran_ue_id.value())); - return true; - } - - [[nodiscard]] bool timeout_handover_command_and_await_handover_cancel() - { - // Fail Handover Preparation (AMF doesn't respond) and await Handover Cancel - if (tick_until(std::chrono::milliseconds(1000), [&]() { return false; })) { - return false; - } - report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu), "Failed to receive Handover Cancel"); - report_fatal_error_if_not(test_helpers::is_valid_handover_cancel(ngap_pdu), "Invalid Handover Cancel"); - return true; - } - - [[nodiscard]] bool send_handover_cancel_ack() - { - // Inject Handover Cancel Ack - get_amf().push_tx_pdu(generate_handover_cancel_ack(ue_ctx->amf_ue_id.value(), ue_ctx->ran_ue_id.value())); - return true; - } - - [[nodiscard]] bool send_handover_command_and_await_ue_context_modification_request() - { - // Inject Handover Command and wait for UE Context Modification Request (containing RRC Reconfiguration) - get_amf().push_tx_pdu(generate_valid_handover_command(ue_ctx->amf_ue_id.value(), ue_ctx->ran_ue_id.value())); - report_fatal_error_if_not( - this->wait_for_f1ap_tx_pdu(du_idx, f1ap_pdu), - "Failed to receive F1AP UE Context Modification Request (containing RRC Reconfiguration)"); - report_fatal_error_if_not(test_helpers::is_valid_ue_context_modification_request(f1ap_pdu), - "Invalid UE Context Modification Request"); - - // Make sure RRC Reconfiguration is valid - const byte_buffer& rrc_container = test_helpers::get_rrc_container(f1ap_pdu); - report_fatal_error_if_not( - test_helpers::is_valid_rrc_reconfiguration(test_helpers::extract_dl_dcch_msg(rrc_container), - false, - std::vector{srb_id_t::srb1, srb_id_t::srb2}, - std::vector{drb_id_t::drb1}), - "Invalid RRC Reconfiguration"); - - return true; - } - - unsigned du_idx = 0; - unsigned cu_up_idx = 0; - - gnb_du_ue_f1ap_id_t du_ue_id = gnb_du_ue_f1ap_id_t::min; - gnb_cu_ue_f1ap_id_t cu_ue_id; - rnti_t crnti = to_rnti(0x4601); - amf_ue_id_t amf_ue_id = uint_to_amf_ue_id( - test_rgen::uniform_int(amf_ue_id_to_uint(amf_ue_id_t::min), amf_ue_id_to_uint(amf_ue_id_t::max))); - gnb_cu_up_ue_e1ap_id_t cu_up_e1ap_id = gnb_cu_up_ue_e1ap_id_t::min; - gnb_cu_cp_ue_e1ap_id_t cu_cp_e1ap_id; - - const ue_context* ue_ctx = nullptr; - - pdu_session_id_t psi = uint_to_pdu_session_id(1); - qos_flow_id_t qfi = uint_to_qos_flow_id(1); - - ngap_message ngap_pdu; - f1ap_message f1ap_pdu; - e1ap_message e1ap_pdu; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Source CU-CP -/////////////////////////////////////////////////////////////////////////////// -TEST_F(cu_cp_inter_cu_handover_test, when_handover_preparation_failure_is_received_then_handover_fails) -{ - // Attach UE - ASSERT_TRUE(attach_ue()); - - // Inject RRC Measurement Report and await Handover Required - ASSERT_TRUE(send_rrc_measurement_report_and_await_handover_required()); - - // Inject Handover Preparation Failure - ASSERT_TRUE(send_handover_preparation_failure()); - - // STATUS: Handover Preparation failed and no further messages are sent to the AMF - report_fatal_error_if_not(not this->get_amf().try_pop_rx_pdu(ngap_pdu), - "there are still NGAP messages to pop from AMF"); -} - -TEST_F(cu_cp_inter_cu_handover_test, when_handover_command_times_out_then_handover_cancel_is_sent) -{ - // Attach UE - ASSERT_TRUE(attach_ue()); - - // Inject RRC Measurement Report and await Handover Required - ASSERT_TRUE(send_rrc_measurement_report_and_await_handover_required()); - - // timeout Handover Command and await Handover Cancel - ASSERT_TRUE(timeout_handover_command_and_await_handover_cancel()); - - // Inject Handover Cancel Ack - ASSERT_TRUE(send_handover_cancel_ack()); -} - -TEST_F(cu_cp_inter_cu_handover_test, when_handover_command_received_then_rrc_reconfiguration_is_sent) -{ - // Attach UE - ASSERT_TRUE(attach_ue()); - - // Inject RRC Measurement Report and await Handover Required - ASSERT_TRUE(send_rrc_measurement_report_and_await_handover_required()); - - // timeout Handover Command and await RRC Reconfiguration - ASSERT_TRUE(send_handover_command_and_await_ue_context_modification_request()); -} - -/////////////////////////////////////////////////////////////////////////////// -// Target CU-CP -/////////////////////////////////////////////////////////////////////////////// -TEST_F(cu_cp_inter_cu_handover_test, when_handover_request_received_then_handover_notify_is_sent) -{ - // Inject Handover Request and await Bearer Context Setup Request - ASSERT_TRUE(send_handover_request_and_await_bearer_context_setup_request()); - - // Inject Bearer Context Setup Response and await UE Context Setup Request - ASSERT_TRUE(send_bearer_context_setup_response_and_await_ue_context_setup_request()); - - // Inject UE Context Setup Response and await Bearer Context Modification Request - ASSERT_TRUE(send_ue_context_setup_response_and_await_bearer_context_modification_request()); - - // Inject Bearer Context Modification Response and await Handover Request Ack - ASSERT_TRUE(send_bearer_context_modification_response_and_await_handover_request_ack()); - - // Inject RRC Reconfiguration Complete and await Handover Notify - ASSERT_TRUE(send_rrc_reconfiguration_complete_and_await_handover_notify()); -} diff --git a/tests/unittests/ngap/ngap_handover_test.cpp b/tests/unittests/ngap/ngap_handover_test.cpp index 51846830d5..7af1b22808 100644 --- a/tests/unittests/ngap/ngap_handover_test.cpp +++ b/tests/unittests/ngap/ngap_handover_test.cpp @@ -39,43 +39,3 @@ TEST_F(ngap_test, when_ue_missing_then_handover_preparation_procedure_fails) // Make sure no NGAP pdu was sent ASSERT_TRUE(n2_gw.last_ngap_msgs.empty()); } - -/// Test successful handover preparation procedure -TEST_F(ngap_test, when_source_gnb_handover_preparation_triggered_then_ho_command_received) -{ - // Setup UE context - ue_index_t ue_index = create_ue(); - run_dl_nas_transport(ue_index); // needed to allocate AMF UE id. - - // Manually add existing PDU sessions to UP manager - add_pdu_session_to_up_manager(ue_index, uint_to_pdu_session_id(1), uint_to_drb_id(0), uint_to_qos_flow_id(0)); - - auto& ue = test_ues.at(ue_index); - ue.rrc_ue_handler.set_ho_preparation_message({}); - - ngap_handover_preparation_request request = - generate_handover_preparation_request(ue_index, - ue_mng.find_ue(ue_index)->get_up_resource_manager().get_pdu_sessions_map(), - nr_cell_identity::create({1, 22}, 1).value(), - 22); - - // Action 1: Launch HO preparation procedure - test_logger.info("Launch source NGAP handover preparation procedure"); - async_task t = ngap->handle_handover_preparation_request(request); - lazy_task_launcher t_launcher(t); - - // Status: AMF received Handover Required. - ASSERT_EQ(n2_gw.last_ngap_msgs.back().pdu.type().value, asn1::ngap::ngap_pdu_c::types_opts::init_msg); - ASSERT_EQ(n2_gw.last_ngap_msgs.back().pdu.init_msg().value.type().value, - asn1::ngap::ngap_elem_procs_o::init_msg_c::types_opts::ho_required); - - ASSERT_FALSE(t.ready()); - - // Inject Handover Command - ngap_message ho_cmd = generate_valid_handover_command(ue.amf_ue_id.value(), ue.ran_ue_id.value()); - ngap->handle_message(ho_cmd); - - // Procedure should have succeeded. - ASSERT_TRUE(t.ready()); - ASSERT_TRUE(t.get().success); -} From 3f7eedf12c62d5696f9436a124a2fa68ed09a927 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 10 Sep 2024 14:24:15 +0100 Subject: [PATCH 039/174] cu_cp: call dlclose on handle, if open --- lib/cu_cp/cu_cp_impl.cpp | 14 ++++++++++++-- lib/cu_cp/cu_cp_impl.h | 12 ++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index cb9f577186..efa7884694 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -99,6 +99,16 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : cu_cp_impl::~cu_cp_impl() { stop(); + + if (dl_handle != nullptr) { + if (::dlclose(dl_handle) != 0) { + char* err = ::dlerror(); + if (err != nullptr) { + fmt::print("Failed to close DL handle: {}\n", err); + logger.error("Failed to close DL handle: {}", err); + } + } + } } bool cu_cp_impl::start() @@ -144,7 +154,7 @@ bool cu_cp_impl::load_plugins() char* err = nullptr; std::string plugin_name = "libsrsran_plugin_ng_handover.so"; - void* dl_handle = ::dlopen(plugin_name.c_str(), RTLD_NOW + RTLD_DEEPBIND + RTLD_GLOBAL); + dl_handle = ::dlopen(plugin_name.c_str(), RTLD_NOW + RTLD_DEEPBIND + RTLD_GLOBAL); if (dl_handle == nullptr) { err = ::dlerror(); if (err != nullptr) { @@ -158,7 +168,7 @@ bool cu_cp_impl::load_plugins() // Load symbol. start_ho_prep_func = reinterpret_cast( - ::dlsym(dl_handle, "_ZN6srsran9srs_cu_cp15testing_funtionERNS_25fifo_async_task_schedulerE")); + ::dlsym(dl_handle, "start_ngap_preparation_procedure_func")); // Handle an error loading the symbol. if (start_ho_prep_func == nullptr) { diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index e3edb80e61..9e6bdc5e2f 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -27,12 +27,23 @@ #include "srsran/cu_cp/cu_cp_types.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" #include "srsran/ran/plmn_identity.h" +#include #include #include namespace srsran { namespace srs_cu_cp { +/// Dynamic library handler deleter - closes the dynamic library upon destruction. +struct dynamic_library_deleter { + void operator()(void* handler) const + { + if (handler != nullptr) { + ::dlclose(handler); + } + } +}; + class cu_cp_common_task_scheduler : public common_task_scheduler { public: @@ -206,6 +217,7 @@ class cu_cp_impl final : public cu_cp, // Plug-ins [[nodiscard]] bool load_plugins(); start_ngap_handover_preparation_procedure_func start_ho_prep_func = nullptr; + void* dl_handle = nullptr; }; } // namespace srs_cu_cp From 5a826cc854d3ce47900b94f8124ee04c839540d7 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 10 Sep 2024 16:32:21 +0100 Subject: [PATCH 040/174] ngap: start handover preparation procedure function declaration --- include/srsran/ngap/ngap_handover.h | 7 +++++-- lib/cu_cp/cu_cp_impl.cpp | 13 +++++-------- lib/cu_cp/cu_cp_impl.h | 10 ---------- lib/ngap/ngap_impl.cpp | 2 +- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/include/srsran/ngap/ngap_handover.h b/include/srsran/ngap/ngap_handover.h index 481d9757b0..12cbf29ddf 100644 --- a/include/srsran/ngap/ngap_handover.h +++ b/include/srsran/ngap/ngap_handover.h @@ -154,8 +154,11 @@ struct ngap_handover_resource_allocation_response { std::optional crit_diagnostics; }; -// Function pointer prototype for starting handover from plugin -using start_ngap_handover_preparation_procedure_func = async_task (*)(); +// Function prototype for starting handover from plugin +async_task +start_ngap_handover_preperation(srslog::basic_logger& logger) asm("start_ngap_preparation_procedure_func"); +using start_ngap_handover_preparation_procedure_func = + async_task (*)(srslog::basic_logger& logger); } // namespace srs_cu_cp } // namespace srsran diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index efa7884694..5510329549 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -69,7 +69,7 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : if (cfg.load_plugins && not load_plugins()) { logger.error("Could not load CU-CP plugins"); - report_fatal_error("Could not load CU-CP plugins"); + report_error("Could not load CU-CP plugins"); } // connect event notifiers to layers @@ -104,7 +104,6 @@ cu_cp_impl::~cu_cp_impl() if (::dlclose(dl_handle) != 0) { char* err = ::dlerror(); if (err != nullptr) { - fmt::print("Failed to close DL handle: {}\n", err); logger.error("Failed to close DL handle: {}", err); } } @@ -158,13 +157,12 @@ bool cu_cp_impl::load_plugins() if (dl_handle == nullptr) { err = ::dlerror(); if (err != nullptr) { - fmt::print("Failed to load HO plugin {}: {}\n", plugin_name, err); + logger.error("Failed to load HO plugin {}: {}", plugin_name, err); } else { - fmt::print("Failed to load HO plugin {}\n", plugin_name); + logger.error("Failed to load HO plugin {}", plugin_name); } return false; } - fmt::print("loaded plugin\n"); // Load symbol. start_ho_prep_func = reinterpret_cast( @@ -174,13 +172,12 @@ bool cu_cp_impl::load_plugins() if (start_ho_prep_func == nullptr) { err = ::dlerror(); if (err != nullptr) { - fmt::print("Error loading symbol {}: {}\n", "testing_function", err); + logger.error("Error loading symbol {}: {}\n", "start_ngap_preparation_procedure_func", err); } else { - fmt::print("Error loading symbol {}:\n", "testing_function"); + logger.error("Error loading symbol {}:\n", "start_ngap_preparation_procedure_func"); } return false; } - fmt::print("loaded start function\n"); return true; } diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index 9e6bdc5e2f..ee40b8246c 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -34,16 +34,6 @@ namespace srsran { namespace srs_cu_cp { -/// Dynamic library handler deleter - closes the dynamic library upon destruction. -struct dynamic_library_deleter { - void operator()(void* handler) const - { - if (handler != nullptr) { - ::dlclose(handler); - } - } -}; - class cu_cp_common_task_scheduler : public common_task_scheduler { public: diff --git a/lib/ngap/ngap_impl.cpp b/lib/ngap/ngap_impl.cpp index 1c7a2fcd22..c5ed1bb142 100644 --- a/lib/ngap/ngap_impl.cpp +++ b/lib/ngap/ngap_impl.cpp @@ -946,7 +946,7 @@ ngap_impl::handle_handover_preparation_request(const ngap_handover_preparation_r ue_ctxt.logger.log_info("Starting HO preparation"); - return (*start_ho_prep_func)(); + return (*start_ho_prep_func)(logger); } void ngap_impl::handle_inter_cu_ho_rrc_recfg_complete(const ue_index_t ue_index, From af27c70ee8036ba37d649f883a58d70661369c82 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 13 Sep 2024 17:06:12 +0100 Subject: [PATCH 041/174] cu_cp: make sure dl libs are linked to cu-cp --- lib/cu_cp/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/cu_cp/CMakeLists.txt b/lib/cu_cp/CMakeLists.txt index 9265a932aa..80561f61dd 100644 --- a/lib/cu_cp/CMakeLists.txt +++ b/lib/cu_cp/CMakeLists.txt @@ -64,4 +64,6 @@ target_link_libraries(srsran_cu_cp srsran_ran srslog srsran_support - srsran_security) + srsran_security + ${CMAKE_DL_LIBS} +) From 20c895dd2965cefb6d924d6cb690a642656d97e0 Mon Sep 17 00:00:00 2001 From: asaezper Date: Fri, 13 Sep 2024 14:27:03 +0200 Subject: [PATCH 042/174] ci: fix typo --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c17a5300ce..61aec530d4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -419,7 +419,7 @@ unit coverage dev: pages: stage: documentation rules: - - if: $CI_DESCRIPTION =~ /ightly Build + Unit Tests/ + - if: $CI_DESCRIPTION =~ /Nightly Build Unit Tests/ when: always # Even if previous stages/required jobs fail allow_failure: true image: ${GITLAB_REGISTRY_URI}/${CI_TOOLS_REPO}/doxygen:1.9.8-1.2023.7 From 2a46467b304a84dc08002fab2f527c11e60b6913 Mon Sep 17 00:00:00 2001 From: asaezper Date: Thu, 12 Sep 2024 17:06:52 +0200 Subject: [PATCH 043/174] ci,e2e: change uesim and viavi testbeds --- .gitlab/ci/e2e.yml | 1 + .gitlab/ci/e2e/.env | 4 ++-- .gitlab/ci/e2e/retina_request_viavi.yml | 15 ++++++++------- .gitlab/ci/e2e/retina_request_zmq_uesim.yml | 12 ++++++------ tests/e2e/tests/test_mode/config_ru.yml | 3 +++ 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/.gitlab/ci/e2e.yml b/.gitlab/ci/e2e.yml index d9e65e27e1..5e32b7573b 100644 --- a/.gitlab/ci/e2e.yml +++ b/.gitlab/ci/e2e.yml @@ -146,6 +146,7 @@ e2e request and config validation: script: - | # Print E2E parameters + echo "GROUP=${GROUP}" echo "TESTBED=${TESTBED}" echo "MARKERS=${MARKERS}" echo "KEYWORDS=${KEYWORDS}" diff --git a/.gitlab/ci/e2e/.env b/.gitlab/ci/e2e/.env index ca56bf5e7c..590ac61c0a 100644 --- a/.gitlab/ci/e2e/.env +++ b/.gitlab/ci/e2e/.env @@ -1,6 +1,6 @@ SRSGNB_REGISTRY_URI=registry.gitlab.com/softwareradiosystems/srsgnb RETINA_REGISTRY_PREFIX=registry.gitlab.com/softwareradiosystems/ci/retina -RETINA_VERSION=0.52.17 +RETINA_VERSION=0.52.18 UBUNTU_VERSION=24.04 AMARISOFT_VERSION=2023-09-08 SRSUE_VERSION=23.11 @@ -9,6 +9,6 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin METRICS_SERVER_VERSION=1.7.3 DPDK_VERSION=23.11.1 ZMQ_HOSTLABEL_0=kubernetes.io/hostname=k8s-worker-vm2 -ZMQ_HOSTLABEL_1=kubernetes.io/hostname=skinny-beast +ZMQ_HOSTLABEL_1=kubernetes.io/hostname=dell-xr12 AMARISOFT_TXRX_BINARY_PATH=../../build_trx_srsran/libtrx_srsran.so GNB_BINARY_PATH=../../build/apps/gnb/gnb diff --git a/.gitlab/ci/e2e/retina_request_viavi.yml b/.gitlab/ci/e2e/retina_request_viavi.yml index 169c43cad7..e62f767a89 100644 --- a/.gitlab/ci/e2e/retina_request_viavi.yml +++ b/.gitlab/ci/e2e/retina_request_viavi.yml @@ -9,21 +9,22 @@ - name: srs-gnb type: gnb image: ${RETINA_REGISTRY_PREFIX}/srsgnb:${RETINA_VERSION} + labels: + - kubernetes.io/hostname=skinny-beast requirements: arch: amd64 cpu: - requests: 20 - limits: 20 + requests: 28 + limits: 28 memory: - requests: "64G" - limits: "64G" + requests: "56G" + limits: "56G" hugepages-1Gi: - requests: 4Gi - limits: 4Gi + requests: 2Gi + limits: 2Gi ephemeral-storage: requests: "50G" limits: "50G" - taints: ["purpose=ci-amd64-avx512-onprem"] resources: - type: emulator model: viavi diff --git a/.gitlab/ci/e2e/retina_request_zmq_uesim.yml b/.gitlab/ci/e2e/retina_request_zmq_uesim.yml index 134cbfba8a..027b555a27 100644 --- a/.gitlab/ci/e2e/retina_request_zmq_uesim.yml +++ b/.gitlab/ci/e2e/retina_request_zmq_uesim.yml @@ -15,8 +15,8 @@ requirements: arch: amd64 cpu: - requests: 4 - limits: 4 + requests: 2 + limits: 2 memory: requests: "4G" limits: "4G" @@ -41,8 +41,8 @@ requirements: arch: amd64 cpu: - requests: 20 - limits: 20 + requests: 16 + limits: 16 memory: requests: "48G" limits: "48G" @@ -63,8 +63,8 @@ requirements: arch: amd64 cpu: - requests: 4 - limits: 4 + requests: 2 + limits: 2 memory: requests: "8G" limits: "8G" diff --git a/tests/e2e/tests/test_mode/config_ru.yml b/tests/e2e/tests/test_mode/config_ru.yml index a1e1943c2e..09a0e1a193 100644 --- a/tests/e2e/tests/test_mode/config_ru.yml +++ b/tests/e2e/tests/test_mode/config_ru.yml @@ -46,6 +46,9 @@ test_mode: expert_execution: affinities: low_priority_cpus: {{low_priority_cpus}} + {% if ru_timing_cpu %} + ru_timing_cpu: {{ ru_timing_cpu }} + {% endif %} cell_affinities: - l1_dl_cpus: {{l1_dl_cpus}} l1_ul_cpus: {{l1_ul_cpus}} From dad76fb8550730e5bc083bcbb9e05f9a51ba1ec3 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 9 Sep 2024 08:49:24 +0200 Subject: [PATCH 044/174] cu_cp: increase procedure timeouts in unit tests and add option to tick timers faster than real time --- .../cu_cp_initial_context_setup_test.cpp | 4 ++-- ...cu_cp_pdu_session_resource_modify_test.cpp | 6 ++++-- ...u_cp_pdu_session_resource_release_test.cpp | 13 +++++++++---- .../cu_cp_pdu_session_resource_setup_test.cpp | 6 ++++-- .../cu_cp/cu_cp_test_environment.cpp | 19 +++++++++++++++++-- .../unittests/cu_cp/cu_cp_test_environment.h | 3 ++- 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp index 60c1e7e405..02189f503d 100644 --- a/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp @@ -317,8 +317,8 @@ TEST_F(cu_cp_initial_context_setup_test, when_ue_capability_enquiry_fails_then_i ASSERT_TRUE(send_security_mode_complete_and_await_ue_capability_enquiry()); // Fail UE Capability Enquiry (UE doesn't respond) - ASSERT_FALSE(tick_until(std::chrono::milliseconds(this->get_cu_cp_cfg().rrc.rrc_procedure_timeout_ms), - [&]() { return false; })); + ASSERT_FALSE(tick_until( + std::chrono::milliseconds(this->get_cu_cp_cfg().rrc.rrc_procedure_timeout_ms), [&]() { return false; }, false)); // Wait for NGAP Initial Context Setup Failure ASSERT_TRUE(await_initial_context_setup_failure()); diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp index cd5fb0bb3c..b491b40202 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp @@ -280,8 +280,10 @@ class cu_cp_pdu_session_resource_modify_test : public cu_cp_test_environment, pu [[nodiscard]] bool timeout_rrc_reconfiguration_and_await_pdu_session_modify_response() { // Fail RRC Reconfiguration (UE doesn't respond) and wait for PDU Session Resource Setup Response - if (tick_until(std::chrono::milliseconds(this->get_cu_cp_cfg().rrc.rrc_procedure_timeout_ms), - [&]() { return false; })) { + if (tick_until( + std::chrono::milliseconds(this->get_cu_cp_cfg().rrc.rrc_procedure_timeout_ms), + [&]() { return false; }, + false)) { return false; } report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu), diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp index ead31e5bef..d02cdfe9a1 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp @@ -246,13 +246,18 @@ class cu_cp_pdu_session_resource_release_test : public cu_cp_test_environment, p return true; } - [[nodiscard]] bool send_rrc_reconfiguration_complete_and_await_pdu_session_setup_response() + [[nodiscard]] bool + send_rrc_reconfiguration_complete_and_await_pdu_session_setup_response(unsigned rrc_recfg_transaction_id = 1, + uint8_t rrc_recfg_count = 9) { // Inject UL RRC Message (containing RRC Reconfiguration Complete) and wait for PDU Session Resource Release // Response get_du(du_idx).push_ul_pdu(test_helpers::create_ul_rrc_message_transfer( - du_ue_id, ue_ctx->cu_ue_id.value(), srb_id_t::srb1, generate_rrc_reconfiguration_complete_pdu(3, 7))); - report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu), + du_ue_id, + ue_ctx->cu_ue_id.value(), + srb_id_t::srb1, + generate_rrc_reconfiguration_complete_pdu(rrc_recfg_transaction_id, rrc_recfg_count))); + report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu, std::chrono::milliseconds(10000)), "Failed to receive PDU Session Resource Release Response"); report_fatal_error_if_not(test_helpers::is_valid_pdu_session_resource_release_response(ngap_pdu), "Invalid PDU Session Resource Setup Response"); @@ -326,5 +331,5 @@ TEST_F(cu_cp_pdu_session_resource_release_test, when_only_pdu_session_released_t ASSERT_TRUE(send_ue_context_modification_response_and_await_rrc_reconfiguration()); // Inject RRC Reconfiguration Complete and await PDU Session Resource Release Response - ASSERT_TRUE(send_rrc_reconfiguration_complete_and_await_pdu_session_setup_response()); + ASSERT_TRUE(send_rrc_reconfiguration_complete_and_await_pdu_session_setup_response(0, 8)); } diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp index 7505a217ad..a8b0d7e510 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp @@ -202,8 +202,10 @@ class cu_cp_pdu_session_resource_setup_test : public cu_cp_test_environment, pub [[nodiscard]] bool timeout_rrc_reconfiguration_and_await_pdu_session_setup_response() { // Fail RRC Reconfiguration (UE doesn't respond) and wait for PDU Session Resource Setup Response - if (tick_until(std::chrono::milliseconds(this->get_cu_cp_cfg().rrc.rrc_procedure_timeout_ms), - [&]() { return false; })) { + if (tick_until( + std::chrono::milliseconds(this->get_cu_cp_cfg().rrc.rrc_procedure_timeout_ms), + [&]() { return false; }, + false)) { return false; } report_fatal_error_if_not(this->wait_for_ngap_tx_pdu(ngap_pdu), diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.cpp b/tests/unittests/cu_cp/cu_cp_test_environment.cpp index 10a678677e..d5d999a6f8 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.cpp +++ b/tests/unittests/cu_cp/cu_cp_test_environment.cpp @@ -192,6 +192,17 @@ cu_cp_test_environment::cu_cp_test_environment(cu_cp_test_env_params params_) : cu_cp_cfg.mobility.meas_manager_config = meas_mng_cfg; } + // > RRC config + cu_cp_cfg.rrc.rrc_procedure_timeout_ms = + std::chrono::milliseconds(10000); // procedure timeouts should only occur intentionally + + // > F1AP config + cu_cp_cfg.f1ap.proc_timeout = std::chrono::milliseconds(10000); // procedure timeouts should only occur intentionally + + // > UE config + cu_cp_cfg.ue.pdu_session_setup_timeout = + std::chrono::seconds(10); // procedure timeouts should only occur intentionally + // create CU-CP instance. cu_cp_inst = create_cu_cp(cu_cp_cfg); } @@ -212,7 +223,9 @@ void cu_cp_test_environment::tick() cu_cp_workers->worker.push_task_blocking([this]() { timers.tick(); }); } -bool cu_cp_test_environment::tick_until(std::chrono::milliseconds timeout, const std::function& stop_condition) +bool cu_cp_test_environment::tick_until(std::chrono::milliseconds timeout, + const std::function& stop_condition, + bool real_time) { std::mutex mutex; std::condition_variable cvar; @@ -240,7 +253,9 @@ bool cu_cp_test_environment::tick_until(std::chrono::milliseconds timeout, const std::unique_lock lock(mutex); cvar.wait(lock, [&done]() { return done; }); } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if (real_time) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } } return stop_condition(); diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.h b/tests/unittests/cu_cp/cu_cp_test_environment.h index 593da8e3e7..f7bcd5529f 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.h +++ b/tests/unittests/cu_cp/cu_cp_test_environment.h @@ -141,7 +141,8 @@ class cu_cp_test_environment void tick(); /// Keep ticking the CU-CP clock until the condition provided returns true. - bool tick_until(std::chrono::milliseconds timeout, const std::function& stop_condition); + bool + tick_until(std::chrono::milliseconds timeout, const std::function& stop_condition, bool real_time = true); /// Tick CU-CP timer until a NGAP PDU is sent. bool wait_for_ngap_tx_pdu(ngap_message& ngap_pdu, From 71f24229ed4b2c26804070d5095b6684e656f57b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 5 Sep 2024 11:22:03 +0200 Subject: [PATCH 045/174] phy: minor equalizer optimization --- lib/phy/upper/equalization/equalize_zf_2xn.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/phy/upper/equalization/equalize_zf_2xn.h b/lib/phy/upper/equalization/equalize_zf_2xn.h index b001c36623..a0b9f1f5c8 100644 --- a/lib/phy/upper/equalization/equalize_zf_2xn.h +++ b/lib/phy/upper/equalization/equalize_zf_2xn.h @@ -66,7 +66,7 @@ void equalize_zf_2xn(span eq_symbols, #if SRSRAN_SIMD_CF_SIZE simd_f_t tx_scaling_simd = srsran_simd_f_set1(tx_scaling); - simd_f_t noise_var_est_simd = srsran_simd_f_set1(noise_var_est); + simd_f_t noise_var_est_simd = srsran_simd_f_set1(noise_var_est / tx_scaling); simd_f_t zero_simd = srsran_simd_f_zero(); simd_f_t infinity_simd = srsran_simd_f_set1(std::numeric_limits::infinity()); @@ -116,13 +116,11 @@ void equalize_zf_2xn(span eq_symbols, } // Calculate the denominators. - simd_f_t d_pinv = srsran_simd_f_mul(tx_scaling_simd, + simd_f_t d_pinv = srsran_simd_f_mul(tx_scaling_simd, srsran_simd_f_sub(srsran_simd_f_mul(norm_sq_ch[0], norm_sq_ch[1]), xi_mod_sq)); - simd_f_t d_nvars = srsran_simd_f_mul(tx_scaling_simd, d_pinv); // Calculate the reciprocal of the denominators. - simd_f_t d_pinv_rcp = srsran_simd_f_rcp(d_pinv); - simd_f_t d_nvars_rcp = srsran_simd_f_rcp(d_nvars); + simd_f_t d_pinv_rcp = srsran_simd_f_rcp(d_pinv); // Apply Zero Forcing algorithm. This is equivalent to multiplying the input signal with the pseudo-inverse of the // channel matrix. @@ -134,8 +132,8 @@ void equalize_zf_2xn(span eq_symbols, symbols_out_l1 = srsran_simd_cf_mul(symbols_out_l1, d_pinv_rcp); // Calculate post-equalization noise variances. - simd_f_t eq_noise_vars_l0 = srsran_simd_f_mul(srsran_simd_f_mul(norm_sq_ch[1], noise_var_est_simd), d_nvars_rcp); - simd_f_t eq_noise_vars_l1 = srsran_simd_f_mul(srsran_simd_f_mul(norm_sq_ch[0], noise_var_est_simd), d_nvars_rcp); + simd_f_t eq_noise_vars_l0 = srsran_simd_f_mul(srsran_simd_f_mul(norm_sq_ch[1], noise_var_est_simd), d_pinv_rcp); + simd_f_t eq_noise_vars_l1 = srsran_simd_f_mul(srsran_simd_f_mul(norm_sq_ch[0], noise_var_est_simd), d_pinv_rcp); // Return values in case of abnormal computation parameters. These include negative, zero, NAN or INF noise // variances and zero, NAN or INF channel estimation coefficients. From 303340d06b5db890249b92c45fd2dae7e53856ec Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 16 Sep 2024 10:35:16 +0200 Subject: [PATCH 046/174] gnb: skip plmn and tac validation for no_core --- apps/gnb/gnb_appconfig_validators.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/gnb/gnb_appconfig_validators.cpp b/apps/gnb/gnb_appconfig_validators.cpp index 1b202c6437..8d84a14c5d 100644 --- a/apps/gnb/gnb_appconfig_validators.cpp +++ b/apps/gnb/gnb_appconfig_validators.cpp @@ -46,6 +46,10 @@ bool srsran::validate_appconfig(const gnb_appconfig& config) bool srsran::validate_plmn_and_tacs(const du_high_unit_config& du_hi_cfg, const cu_cp_unit_config& cu_cp_cfg) { + if (cu_cp_cfg.amf_config.no_core) { + return true; + } + std::vector supported_tas; for (const auto& supported_ta : cu_cp_cfg.amf_config.amf.supported_tas) { From 836a6aff11ce4a96ab16a108153de64e5808032a Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 5 Sep 2024 09:49:55 +0200 Subject: [PATCH 047/174] ru_dummy: add event metrics --- lib/ru/dummy/ru_dummy_impl.cpp | 11 +++++++++- lib/ru/dummy/ru_dummy_sector.h | 40 +++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/ru/dummy/ru_dummy_impl.cpp b/lib/ru/dummy/ru_dummy_impl.cpp index 5256534a41..68a74385f0 100644 --- a/lib/ru/dummy/ru_dummy_impl.cpp +++ b/lib/ru/dummy/ru_dummy_impl.cpp @@ -82,7 +82,16 @@ void ru_dummy_impl::stop() void ru_dummy_impl::print_metrics() { - fmt::print("No statistics implemented."); + fmt::print("| {:^11} | {:^11} | {:^11} | {:^11} | {:^11} | {:^11} |\n", + "DL Count", + "DL Late", + "UL Count", + "UL Late", + "PRACH Count", + "PRACH Late"); + for (auto& sector : sectors) { + sector.print_metrics(); + } } void ru_dummy_impl::loop() diff --git a/lib/ru/dummy/ru_dummy_sector.h b/lib/ru/dummy/ru_dummy_sector.h index 382cc99aaf..058523ee71 100644 --- a/lib/ru/dummy/ru_dummy_sector.h +++ b/lib/ru/dummy/ru_dummy_sector.h @@ -69,12 +69,14 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane std::lock_guard lock(dl_request_mutex); request_information info = {context, grid.copy()}; std::swap(info, dl_request[context.slot.system_slot()]); + ++total_dl_request_count; // If the previous slot is valid, it is a late. if (info.context.slot.valid()) { logger.warning("Real-time failure in RU: received late DL request from slot {} in sector {}.", info.context.slot, info.context.sector); + ++late_dl_request_count; } } @@ -83,6 +85,7 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane { std::lock_guard lock(prach_request_mutex); prach_buffer_context info = std::exchange(prach_request[context.slot.system_slot()], context); + ++total_prach_request_count; // Detect if there is an unhandled request from a different slot. if (info.slot.valid()) { @@ -91,6 +94,7 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane "Real-time failure in RU: received late PRACH request from slot {} in sector {}.", info.slot, info.sector); + ++late_prach_request_count; } } @@ -100,6 +104,7 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane std::lock_guard lock(ul_request_mutex); request_information info = {context, grid.copy()}; std::swap(info, ul_request[context.slot.system_slot()]); + ++total_ul_request_count; // Detect if there is an unhandled request from a different slot. if (info.context.slot.valid()) { @@ -108,6 +113,7 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane "Real-time failure in RU: received late UL request from slot {} in sector {}.", info.context.slot, info.context.sector); + ++late_ul_request_count; } } @@ -130,6 +136,7 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane "Real-time failure in RU: detected late DL request from slot {} in sector {}.", dl_info.context.slot, dl_info.context.sector); + ++late_dl_request_count; } // Process UL request for this slot. @@ -150,7 +157,7 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane // Notify received resource grid for each symbol. for (unsigned i_symbol = 0; i_symbol != MAX_NSYMB_PER_SLOT; ++i_symbol) { rx_context.symbol_id = i_symbol; - symbol_notifier.on_new_uplink_symbol(rx_context, std::move(ul_info.grid)); + symbol_notifier.on_new_uplink_symbol(rx_context, ul_info.grid); } } else { @@ -160,6 +167,7 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane "Real-time failure in RU: detected late UL request from slot {} in sector {}.", ul_info.context.slot, ul_info.context.sector); + ++late_ul_request_count; } } @@ -182,10 +190,23 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane "Real-time failure in RU: detected late PRACH request from slot {} in sector {}.", prach_context.slot, prach_context.sector); + ++late_prach_request_count; } } } + /// Prints in \c stdout the current gathered metrics. It does not reset the metrics. + void print_metrics() const + { + fmt::print("| {:^11} | {:^11} | {:^11} | {:^11} | {:^11} | {:^11} |\n", + total_dl_request_count.load(), + late_dl_request_count.load(), + total_ul_request_count.load(), + late_ul_request_count.load(), + total_prach_request_count.load(), + late_prach_request_count.load()); + } + private: /// Maximum number of requests stored in the ring buffers. static constexpr unsigned max_nof_request = 40; @@ -217,6 +238,23 @@ class ru_dummy_sector : public ru_uplink_plane_handler, public ru_downlink_plane circular_array dl_request; /// Protects the circular buffer containing the DL requests. std::mutex dl_request_mutex; + /// \name Group of event counters. + /// + /// These counters are informative and printed when print_metrics() is called. + /// @{ + /// Total number of UL receive requests. + std::atomic total_ul_request_count = {}; + /// Total number of DL transmit requests. + std::atomic total_dl_request_count = {}; + /// Total number of PRACH receive requests. + std::atomic total_prach_request_count = {}; + /// Number of late UL receive request. + std::atomic late_ul_request_count = {}; + /// Number of late DL transmit request. + std::atomic late_dl_request_count = {}; + /// Number of late PRACH receive request. + std::atomic late_prach_request_count = {}; + /// @} }; } // namespace srsran From a88da58bd3f6d5e4a38726922f24a9ed26ad95dc Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 16 Sep 2024 09:48:16 +0200 Subject: [PATCH 048/174] ci,e2e: fix config in viavi tests --- tests/e2e/tests/viavi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index c2ee08d1df..a3a92b71e9 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -91,7 +91,7 @@ def load_yaml_config(config_filename: str) -> List[_ViaviConfiguration]: gnb_extra_commands=test_declaration["gnb_extra_commands"], id=test_declaration["id"], max_pdschs_per_slot=test_declaration["max_pdschs_per_slot"], - max_puschs_per_slot=test_declaration["max_pdschs_per_slot"], + max_puschs_per_slot=test_declaration["max_puschs_per_slot"], enable_qos_viavi=test_declaration["enable_qos_viavi"], expected_dl_bitrate=test_declaration["expected_dl_bitrate"], expected_ul_bitrate=test_declaration["expected_ul_bitrate"], From e756b1cdd45654c020f51bd0b4eba389b6d72d68 Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 16 Sep 2024 09:48:31 +0200 Subject: [PATCH 049/174] ci: update docker compose test with new amf config --- .gitlab/ci/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/ci/docker.yml b/.gitlab/ci/docker.yml index f59be224f4..f690b59375 100644 --- a/.gitlab/ci/docker.yml +++ b/.gitlab/ci/docker.yml @@ -160,7 +160,7 @@ gnb docker compose uhd: variables: <<: *uhd_params script: - - sh -c "docker compose -f docker/docker-compose.yml run --no-deps gnb gnb amf --no_core=true ru_sdr --device_driver uhd | grep 'Failed to open device with address'" + - sh -c "docker compose -f docker/docker-compose.yml run --no-deps gnb gnb cu_cp amf --no_core=true ru_sdr --device_driver uhd | grep 'Failed to open device with address'" gnb docker compose dpdk: extends: .gnb docker compose @@ -168,7 +168,7 @@ gnb docker compose dpdk: <<: *dpdk_params script: - sh -c "docker compose -f docker/docker-compose.yml run --no-deps gnb which ru_emulator" - - sh -c "docker compose -f docker/docker-compose.yml run --no-deps gnb gnb amf --no_core=true hal --eal_args='--help'" + - sh -c "docker compose -f docker/docker-compose.yml run --no-deps gnb gnb cu_cp amf --no_core=true hal --eal_args='--help'" 5gc docker compose: extends: .docker compose From ef983b64bdaf6dd77918ffc5365e5a97a8088aef Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 16 Sep 2024 09:57:57 +0200 Subject: [PATCH 050/174] config: update amf parameter change --- configs/cu.yml | 13 +- configs/gnb_custom_cell_properties.yml | 62 +++++----- configs/gnb_rf_b200_tdd_n78_20mhz.yml | 58 +++++---- configs/gnb_rf_b210_fdd_srsUE.yml | 66 ++++++----- configs/gnb_rf_n310_fdd_n3_20mhz.yml | 56 +++++---- configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml | 94 ++++++++------- configs/gnb_ru_ran550_tdd_n78_100mhz_4x2.yml | 112 ++++++++++-------- configs/gnb_ru_ran550_tdd_n78_20mhz.yml | 104 ++++++++-------- .../gnb_ru_rpqn4800e_tdd_n78_20mhz_2x2.yml | 106 +++++++++-------- 9 files changed, 371 insertions(+), 300 deletions(-) diff --git a/configs/cu.yml b/configs/cu.yml index 1e11e89f6a..f5a12b1075 100644 --- a/configs/cu.yml +++ b/configs/cu.yml @@ -1,9 +1,16 @@ # Example config for a locally deployed CU listening on the localhost interface for a DU connection -amf: - addr: 127.0.1.100 - bind_addr: 127.0.10.2 cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.10.2 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 f1ap: bind_addr: 127.0.10.1 diff --git a/configs/gnb_custom_cell_properties.yml b/configs/gnb_custom_cell_properties.yml index 650308c644..a70e43d371 100644 --- a/configs/gnb_custom_cell_properties.yml +++ b/configs/gnb_custom_cell_properties.yml @@ -1,42 +1,50 @@ -# This example configuration outlines how to use the 'cells' subcommand. The base cell configuration is -# for all cells using the 'cell_cfg' subcommand, with the 'cell' subcommand being used to overwrite this -# base configuration for a single cell. +# This example configuration outlines how to use the 'cells' subcommand. The base cell configuration is +# for all cells using the 'cell_cfg' subcommand, with the 'cell' subcommand being used to overwrite this +# base configuration for a single cell. -amf: - addr: 127.0.1.100 - bind_addr: 127.0.0.1 +cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.0.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_sdr: - device_driver: uhd - device_args: type=b200,num_recv_frames=64,num_send_frames=64 - clock: - sync: - srate: 23.04 + device_driver: uhd + device_args: type=b200,num_recv_frames=64,num_send_frames=64 + clock: + sync: + srate: 23.04 otw_format: sc12 - tx_gain: 50 - rx_gain: 60 + tx_gain: 50 + rx_gain: 60 # Properties set in this section are inherited for all cells unless overridden inside the cells section. cell_cfg: - dl_arfcn: 632628 - band: 78 - channel_bandwidth_MHz: 20 - common_scs: 30 - plmn: "00101" - tac: 7 - pci: 1 + dl_arfcn: 632628 + band: 78 + channel_bandwidth_MHz: 20 + common_scs: 30 + plmn: "00101" + tac: 7 + pci: 1 # This section is represented as an array of cells. For this example, a single cell is declared that overrides the PCI and channel bandwidth properties from the default values. cells: - - pci: 10 - channel_bandwidth_MHz: 10 + - pci: 10 + channel_bandwidth_MHz: 10 log: filename: /tmp/gnb.log - all_level: warning + all_level: warning pcap: - mac_enable: false - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: false - ngap_filename: /tmp/gnb_ngap.pcap \ No newline at end of file + mac_enable: false + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: false + ngap_filename: /tmp/gnb_ngap.pcap diff --git a/configs/gnb_rf_b200_tdd_n78_20mhz.yml b/configs/gnb_rf_b200_tdd_n78_20mhz.yml index d02318d5e2..a3a59452bf 100644 --- a/configs/gnb_rf_b200_tdd_n78_20mhz.yml +++ b/configs/gnb_rf_b200_tdd_n78_20mhz.yml @@ -1,35 +1,43 @@ # This example configuration outlines how to configure the srsRAN Project gNB to create a single TDD cell -# transmitting in band 78, with 20 MHz bandwidth and 30 kHz sub-carrier-spacing. A USRP B200 is configured -# as the RF frontend using split 8. Note in this example an external clock source is not used, so the sync -# is not defined and the default is used. +# transmitting in band 78, with 20 MHz bandwidth and 30 kHz sub-carrier-spacing. A USRP B200 is configured +# as the RF frontend using split 8. Note in this example an external clock source is not used, so the sync +# is not defined and the default is used. -amf: - addr: 127.0.1.100 - bind_addr: 127.0.0.1 +cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.0.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_sdr: - device_driver: uhd - device_args: type=b200,num_recv_frames=64,num_send_frames=64 - srate: 23.04 - otw_format: sc12 - tx_gain: 80 - rx_gain: 40 + device_driver: uhd + device_args: type=b200,num_recv_frames=64,num_send_frames=64 + srate: 23.04 + otw_format: sc12 + tx_gain: 80 + rx_gain: 40 cell_cfg: - dl_arfcn: 632628 - band: 78 - channel_bandwidth_MHz: 20 - common_scs: 30 - plmn: "00101" - tac: 7 - pci: 1 + dl_arfcn: 632628 + band: 78 + channel_bandwidth_MHz: 20 + common_scs: 30 + plmn: "00101" + tac: 7 + pci: 1 log: - filename: /tmp/gnb.log - all_level: warning + filename: /tmp/gnb.log + all_level: warning pcap: - mac_enable: false - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: false - ngap_filename: /tmp/gnb_ngap.pcap \ No newline at end of file + mac_enable: false + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: false + ngap_filename: /tmp/gnb_ngap.pcap diff --git a/configs/gnb_rf_b210_fdd_srsUE.yml b/configs/gnb_rf_b210_fdd_srsUE.yml index 9940c4aea1..5096a1c434 100644 --- a/configs/gnb_rf_b210_fdd_srsUE.yml +++ b/configs/gnb_rf_b210_fdd_srsUE.yml @@ -1,45 +1,53 @@ # This example configuration outlines how to configure the srsRAN Project gNB to create a single FDD cell -# transmitting in band 3, with 20 MHz bandwidth and 15 kHz sub-carrier-spacing. A USRP B200 is configured -# as the RF frontend using split 8, with a Leo Bodnar GPSDO as an external reference clock. +# transmitting in band 3, with 20 MHz bandwidth and 15 kHz sub-carrier-spacing. A USRP B200 is configured +# as the RF frontend using split 8, with a Leo Bodnar GPSDO as an external reference clock. -# This particular configuration is intended to be used with srsUE. Note the `pdcch` parameters set in the -# `cell_cfg` section. These are set to match the capabilities of srsUE. +# This particular configuration is intended to be used with srsUE. Note the `pdcch` parameters set in the +# `cell_cfg` section. These are set to match the capabilities of srsUE. -amf: - addr: 10.53.1.2 - bind_addr: 10.53.1.1 +cu_cp: + amf: + addr: 10.53.1.2 + port: 38412 + bind_addr: 10.53.1.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_sdr: - device_driver: uhd - device_args: type=b200 + device_driver: uhd + device_args: type=b200 clock: external - srate: 23.04 - tx_gain: 80 - rx_gain: 40 + srate: 23.04 + tx_gain: 80 + rx_gain: 40 cell_cfg: - dl_arfcn: 368500 - band: 3 - channel_bandwidth_MHz: 20 - common_scs: 15 - plmn: "00101" - tac: 7 + dl_arfcn: 368500 + band: 3 + channel_bandwidth_MHz: 20 + common_scs: 15 + plmn: "00101" + tac: 7 pdcch: dedicated: - ss2_type: common - dci_format_0_1_and_1_1: false + ss2_type: common + dci_format_0_1_and_1_1: false common: - ss0_index: 0 - coreset0_index: 12 + ss0_index: 0 + coreset0_index: 12 prach: - prach_config_index: 1 + prach_config_index: 1 log: - filename: /tmp/gnb.log - all_level: info + filename: /tmp/gnb.log + all_level: info pcap: - mac_enable: enable - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: enable - ngap_filename: /tmp/gnb_ngap.pcap + mac_enable: enable + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: enable + ngap_filename: /tmp/gnb_ngap.pcap diff --git a/configs/gnb_rf_n310_fdd_n3_20mhz.yml b/configs/gnb_rf_n310_fdd_n3_20mhz.yml index 4ebc6671cc..9e717ef86a 100644 --- a/configs/gnb_rf_n310_fdd_n3_20mhz.yml +++ b/configs/gnb_rf_n310_fdd_n3_20mhz.yml @@ -1,35 +1,43 @@ # This example configuration outlines how to configure the srsRAN Project gNB to create a single FDD cell -# transmitting in band 3, with 20 MHz bandwidth and 30 kHz sub-carrier-spacing. A USRP N3XX is configured +# transmitting in band 3, with 20 MHz bandwidth and 30 kHz sub-carrier-spacing. A USRP N3XX is configured # as the RF frontend using split 8. Note in this example the internal GPDSO of the N310 is used. -amf: - addr: 127.0.1.100 - bind_addr: 127.0.0.1 +cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.0.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_sdr: - device_driver: uhd - device_args: type=n3xx - clock: gpsdo - sync: gpsdo - srate: 30.72 - tx_gain: 35 - rx_gain: 60 + device_driver: uhd + device_args: type=n3xx + clock: gpsdo + sync: gpsdo + srate: 30.72 + tx_gain: 35 + rx_gain: 60 cell_cfg: - dl_arfcn: 368640 - band: 3 - channel_bandwidth_MHz: 20 - common_scs: 15 - plmn: "00101" - tac: 7 - pci: 1 + dl_arfcn: 368640 + band: 3 + channel_bandwidth_MHz: 20 + common_scs: 15 + plmn: "00101" + tac: 7 + pci: 1 log: - filename: /tmp/gnb.log - all_level: info + filename: /tmp/gnb.log + all_level: info pcap: - mac_enable: false - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: false - ngap_filename: /tmp/gnb_ngap.pcap \ No newline at end of file + mac_enable: false + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: false + ngap_filename: /tmp/gnb_ngap.pcap diff --git a/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml b/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml index ff110ac74c..fde60b2470 100644 --- a/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml +++ b/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml @@ -2,60 +2,68 @@ # with the Picocom PC802 SCB. This config will create a single TDD cell transmitting in band 78, with 20 MHz bandwidth and 30 kHz sub-carrier-spacing. # The parameters used to configure the RU are found in the `ru_ofh` sub-section. This configuration makes used of the OFH Lib from SRS to enable split 7.2. -amf: - addr: 127.0.1.100 - bind_addr: 127.0.0.1 +cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.0.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_ofh: - t1a_max_cp_dl: 350 - t1a_min_cp_dl: 250 - t1a_max_cp_ul: 250 - t1a_min_cp_ul: 150 - t1a_max_up: 200 - t1a_min_up: 80 + t1a_max_cp_dl: 350 + t1a_min_cp_dl: 250 + t1a_max_cp_ul: 250 + t1a_min_cp_ul: 150 + t1a_max_up: 200 + t1a_min_up: 80 ta4_max: 500 - ta4_min: 10 - is_prach_cp_enabled: false - compr_method_ul: bfp - compr_bitwidth_ul: 9 - compr_method_dl: bfp - compr_bitwidth_dl: 9 - compr_method_prach: bfp - compr_bitwidth_prach: 9 - iq_scaling: 1.0 + ta4_min: 10 + is_prach_cp_enabled: false + compr_method_ul: bfp + compr_bitwidth_ul: 9 + compr_method_dl: bfp + compr_bitwidth_dl: 9 + compr_method_prach: bfp + compr_bitwidth_prach: 9 + iq_scaling: 1.0 cells: - - network_interface: enp1s0f0 - ru_mac_addr: ce:fc:6c:09:a6:cd - du_mac_addr: 80:61:5f:0d:df:aa - vlan_tag_cp: 3 - vlan_tag_up: 3 - prach_port_id: [0] - dl_port_id: [0] - ul_port_id: [0] + - network_interface: enp1s0f0 + ru_mac_addr: ce:fc:6c:09:a6:cd + du_mac_addr: 80:61:5f:0d:df:aa + vlan_tag_cp: 3 + vlan_tag_up: 3 + prach_port_id: [0] + dl_port_id: [0] + ul_port_id: [0] cell_cfg: - dl_arfcn: 625000 - band: 78 - channel_bandwidth_MHz: 20 - common_scs: 30 - plmn: "00101" - tac: 7 - pci: 1 + dl_arfcn: 625000 + band: 78 + channel_bandwidth_MHz: 20 + common_scs: 30 + plmn: "00101" + tac: 7 + pci: 1 prach: - prach_config_index: 159 - prach_root_sequence_index: 1 - zero_correlation_zone: 0 - prach_frequency_start: 0 + prach_config_index: 159 + prach_root_sequence_index: 1 + zero_correlation_zone: 0 + prach_frequency_start: 0 tdd_ul_dl_cfg: nof_dl_slots: 7 nof_ul_slots: 2 log: - filename: /tmp/gnb.log - all_level: warning + filename: /tmp/gnb.log + all_level: warning pcap: - mac_enable: false - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: false - ngap_filename: /tmp/gnb_ngap.pcap + mac_enable: false + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: false + ngap_filename: /tmp/gnb_ngap.pcap diff --git a/configs/gnb_ru_ran550_tdd_n78_100mhz_4x2.yml b/configs/gnb_ru_ran550_tdd_n78_100mhz_4x2.yml index 9e0a4824d4..58b3cc4339 100644 --- a/configs/gnb_ru_ran550_tdd_n78_100mhz_4x2.yml +++ b/configs/gnb_ru_ran550_tdd_n78_100mhz_4x2.yml @@ -2,67 +2,75 @@ # with the Benetel R550 RU. This config will create a single TDD MIMO cell transmitting in band 78, with 100 MHz bandwidth and 30 kHz sub-carrier-spacing. # The parameters used to configure the RU are found in the `ru_ofh` sub-section. This configuration makes used of the OFH Lib from SRS to enable split 7.2. -amf: - addr: 127.0.1.100 - bind_addr: 127.0.0.1 +cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.0.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_ofh: - t1a_max_cp_dl: 535 - t1a_min_cp_dl: 286 - t1a_max_cp_ul: 535 - t1a_min_cp_ul: 286 - t1a_max_up: 390 - t1a_min_up: 80 - ta4_max: 500 - ta4_min: 25 - is_prach_cp_enabled: false - compr_method_ul: bfp - compr_bitwidth_ul: 9 - compr_method_dl: bfp - compr_bitwidth_dl: 9 - compr_method_prach: bfp - compr_bitwidth_prach: 9 - enable_ul_static_compr_hdr: true - enable_dl_static_compr_hdr: true - iq_scaling: 5.5 + t1a_max_cp_dl: 535 + t1a_min_cp_dl: 286 + t1a_max_cp_ul: 535 + t1a_min_cp_ul: 286 + t1a_max_up: 390 + t1a_min_up: 80 + ta4_max: 500 + ta4_min: 25 + is_prach_cp_enabled: false + compr_method_ul: bfp + compr_bitwidth_ul: 9 + compr_method_dl: bfp + compr_bitwidth_dl: 9 + compr_method_prach: bfp + compr_bitwidth_prach: 9 + enable_ul_static_compr_hdr: true + enable_dl_static_compr_hdr: true + iq_scaling: 5.5 cells: - - network_interface: enp1s0f0 - ru_mac_addr: 70:b3:d5:e1:5b:06 - du_mac_addr: 80:61:5f:0d:df:aa - vlan_tag_cp: 5 - vlan_tag_up: 5 - prach_port_id: [4, 5] - dl_port_id: [0, 1, 2, 3] - ul_port_id: [0, 1] + - network_interface: enp1s0f0 + ru_mac_addr: 70:b3:d5:e1:5b:06 + du_mac_addr: 80:61:5f:0d:df:aa + vlan_tag_cp: 5 + vlan_tag_up: 5 + prach_port_id: [4, 5] + dl_port_id: [0, 1, 2, 3] + ul_port_id: [0, 1] cell_cfg: - dl_arfcn: 637212 - band: 78 - channel_bandwidth_MHz: 100 - common_scs: 30 - plmn: "00101" - tac: 7 - pci: 1 - nof_antennas_dl: 4 - nof_antennas_ul: 2 + dl_arfcn: 637212 + band: 78 + channel_bandwidth_MHz: 100 + common_scs: 30 + plmn: "00101" + tac: 7 + pci: 1 + nof_antennas_dl: 4 + nof_antennas_ul: 2 prach: - prach_config_index: 7 - prach_root_sequence_index: 1 - zero_correlation_zone: 0 - prach_frequency_start: 0 + prach_config_index: 7 + prach_root_sequence_index: 1 + zero_correlation_zone: 0 + prach_frequency_start: 0 tdd_ul_dl_cfg: - dl_ul_tx_period: 10 - nof_dl_slots: 7 - nof_dl_symbols: 6 - nof_ul_slots: 2 + dl_ul_tx_period: 10 + nof_dl_slots: 7 + nof_dl_symbols: 6 + nof_ul_slots: 2 nof_ul_symbols: 4 log: - filename: /tmp/gnb.log - all_level: warning + filename: /tmp/gnb.log + all_level: warning pcap: - mac_enable: false - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: false - ngap_filename: /tmp/gnb_ngap.pcap + mac_enable: false + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: false + ngap_filename: /tmp/gnb_ngap.pcap diff --git a/configs/gnb_ru_ran550_tdd_n78_20mhz.yml b/configs/gnb_ru_ran550_tdd_n78_20mhz.yml index d69886ba59..e8e86c289f 100644 --- a/configs/gnb_ru_ran550_tdd_n78_20mhz.yml +++ b/configs/gnb_ru_ran550_tdd_n78_20mhz.yml @@ -2,61 +2,69 @@ # with the Benetel R550 RU. This config will create a single TDD MIMO cell transmitting in band 78, with 20 MHz bandwidth and 30 kHz sub-carrier-spacing. # The parameters used to configure the RU are found in the `ru_ofh` sub-section. This configuration makes used of the OFH Lib from SRS to enable split 7.2. -amf: - addr: 127.0.1.100 - bind_addr: 127.0.0.1 +cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.0.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_ofh: - ru_bandwidth_MHz: 100 - t1a_max_cp_dl: 535 - t1a_min_cp_dl: 286 - t1a_max_cp_ul: 535 - t1a_min_cp_ul: 286 - t1a_max_up: 390 - t1a_min_up: 80 - ta4_max: 500 - ta4_min: 25 - is_prach_cp_enabled: false - is_dl_broadcast_enabled: true - compr_method_ul: bfp - compr_bitwidth_ul: 9 - compr_method_dl: bfp - compr_method_prach: bfp - compr_bitwidth_prach: 9 - compr_bitwidth_dl: 9 - enable_ul_static_compr_hdr: true - enable_dl_static_compr_hdr: true - iq_scaling: 5.5 + ru_bandwidth_MHz: 100 + t1a_max_cp_dl: 535 + t1a_min_cp_dl: 286 + t1a_max_cp_ul: 535 + t1a_min_cp_ul: 286 + t1a_max_up: 390 + t1a_min_up: 80 + ta4_max: 500 + ta4_min: 25 + is_prach_cp_enabled: false + is_dl_broadcast_enabled: true + compr_method_ul: bfp + compr_bitwidth_ul: 9 + compr_method_dl: bfp + compr_method_prach: bfp + compr_bitwidth_prach: 9 + compr_bitwidth_dl: 9 + enable_ul_static_compr_hdr: true + enable_dl_static_compr_hdr: true + iq_scaling: 5.5 cells: - - network_interface: enp1s0f0 - ru_mac_addr: 70:b3:d5:e1:5b:06 - du_mac_addr: 80:61:5f:0d:df:aa - vlan_tag_cp: 5 - vlan_tag_up: 5 - prach_port_id: [4] - dl_port_id: [0, 1] - ul_port_id: [0] + - network_interface: enp1s0f0 + ru_mac_addr: 70:b3:d5:e1:5b:06 + du_mac_addr: 80:61:5f:0d:df:aa + vlan_tag_cp: 5 + vlan_tag_up: 5 + prach_port_id: [4] + dl_port_id: [0, 1] + ul_port_id: [0] cell_cfg: - dl_arfcn: 634548 - band: 78 - channel_bandwidth_MHz: 20 - common_scs: 30 - plmn: "00101" - tac: 7 - pci: 1 + dl_arfcn: 634548 + band: 78 + channel_bandwidth_MHz: 20 + common_scs: 30 + plmn: "00101" + tac: 7 + pci: 1 prach: - prach_config_index: 7 - prach_root_sequence_index: 1 - zero_correlation_zone: 0 - prach_frequency_start: 0 + prach_config_index: 7 + prach_root_sequence_index: 1 + zero_correlation_zone: 0 + prach_frequency_start: 0 log: - filename: /tmp/gnb.log - all_level: warning + filename: /tmp/gnb.log + all_level: warning pcap: - mac_enable: false - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: false - ngap_filename: /tmp/gnb_ngap.pcap + mac_enable: false + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: false + ngap_filename: /tmp/gnb_ngap.pcap diff --git a/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz_2x2.yml b/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz_2x2.yml index f1c1d660cd..b777656654 100644 --- a/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz_2x2.yml +++ b/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz_2x2.yml @@ -2,64 +2,72 @@ # with the Foxconn RPQN O-RU. This config will create a single TDD cell transmitting in band n78, with 20 MHz bandwidth and 30 kHz sub-carrier-spacing. # The parameters used to configure the RU are found in the `ru_ofh` sub-section. This configuration makes used of the OFH Lib from SRS to enable split 7.2. -amf: - addr: 127.0.1.100 - bind_addr: 127.0.0.1 +cu_cp: + amf: + addr: 127.0.1.100 + port: 38412 + bind_addr: 127.0.0.1 + supported_tracking_areas: + - tac: 7 + plmn_list: + - plmn: "00101" + tai_slice_support_list: + - sst: 1 ru_ofh: - t1a_max_cp_dl: 420 - t1a_min_cp_dl: 250 - t1a_max_cp_ul: 420 - t1a_min_cp_ul: 250 - t1a_max_up: 196 - t1a_min_up: 80 - ta4_max: 500 - ta4_min: 25 - is_prach_cp_enabled: true - ignore_ecpri_payload_size: true - compr_method_ul: bfp - compr_bitwidth_ul: 9 - compr_method_dl: bfp - compr_bitwidth_dl: 9 - compr_method_prach: bfp - compr_bitwidth_prach: 9 - enable_ul_static_compr_hdr: false - enable_dl_static_compr_hdr: false - iq_scaling: 1.0 + t1a_max_cp_dl: 420 + t1a_min_cp_dl: 250 + t1a_max_cp_ul: 420 + t1a_min_cp_ul: 250 + t1a_max_up: 196 + t1a_min_up: 80 + ta4_max: 500 + ta4_min: 25 + is_prach_cp_enabled: true + ignore_ecpri_payload_size: true + compr_method_ul: bfp + compr_bitwidth_ul: 9 + compr_method_dl: bfp + compr_bitwidth_dl: 9 + compr_method_prach: bfp + compr_bitwidth_prach: 9 + enable_ul_static_compr_hdr: false + enable_dl_static_compr_hdr: false + iq_scaling: 1.0 cells: - - network_interface: 0000:01:00.1 - ru_mac_addr: 6c:ad:ad:00:xx:xx - du_mac_addr: 50:7c:6f:55:xx:xx - vlan_tag_cp: 2 - vlan_tag_up: 2 - prach_port_id: [4, 5, 6, 7] - dl_port_id: [0, 1] - ul_port_id: [0, 1, 2, 3] + - network_interface: 0000:01:00.1 + ru_mac_addr: 6c:ad:ad:00:xx:xx + du_mac_addr: 50:7c:6f:55:xx:xx + vlan_tag_cp: 2 + vlan_tag_up: 2 + prach_port_id: [4, 5, 6, 7] + dl_port_id: [0, 1] + ul_port_id: [0, 1, 2, 3] cell_cfg: - dl_arfcn: 640000 - band: 78 - channel_bandwidth_MHz: 20 - common_scs: 30 - plmn: "00101" - tac: 7 - pci: 1 - nof_antennas_dl: 2 - nof_antennas_ul: 2 + dl_arfcn: 640000 + band: 78 + channel_bandwidth_MHz: 20 + common_scs: 30 + plmn: "00101" + tac: 7 + pci: 1 + nof_antennas_dl: 2 + nof_antennas_ul: 2 prach: - prach_config_index: 159 - prach_root_sequence_index: 1 - zero_correlation_zone: 0 - prach_frequency_start: 12 + prach_config_index: 159 + prach_root_sequence_index: 1 + zero_correlation_zone: 0 + prach_frequency_start: 12 pdsch: mcs_table: qam256 log: - filename: /tmp/gnb.log - all_level: warning + filename: /tmp/gnb.log + all_level: warning pcap: - mac_enable: false - mac_filename: /tmp/gnb_mac.pcap - ngap_enable: false - ngap_filename: /tmp/gnb_ngap.pcap \ No newline at end of file + mac_enable: false + mac_filename: /tmp/gnb_mac.pcap + ngap_enable: false + ngap_filename: /tmp/gnb_ngap.pcap From f264d6aa8b8c1bf72de832a42eaa84ce28880a86 Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 16 Sep 2024 10:02:33 +0200 Subject: [PATCH 051/174] ci: increase exit timeout when asan --- .gitlab/ci/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index 093c1a6cca..43dfafdc03 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -1825,7 +1825,7 @@ basic asan: variables: TEST_MODE: none MARCH: x86-64-v3 - BUILD_ARGS: -DEXIT_TIMEOUT=15 + BUILD_ARGS: -DEXIT_TIMEOUT=60 tags: ["${AMD64_AVX2_TAG}"] after_script: - *build_after_script From 30152d856fa43e06f7a2f31175ac62f1688987f5 Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 16 Sep 2024 12:40:06 +0200 Subject: [PATCH 052/174] ci,e2e: increase inter ue power one time in some uesim tests --- tests/e2e/tests/iperf.py | 8 ++++++-- tests/e2e/tests/steps/stub.py | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/e2e/tests/iperf.py b/tests/e2e/tests/iperf.py index 7c1d4d1d11..15c5129513 100644 --- a/tests/e2e/tests/iperf.py +++ b/tests/e2e/tests/iperf.py @@ -26,7 +26,7 @@ from retina.protocol.ue_pb2_grpc import UEStub from .steps.configuration import configure_test_parameters, get_minimum_sample_rate_for_bandwidth, is_tdd -from .steps.stub import iperf_parallel, start_and_attach, stop +from .steps.stub import INTER_UE_START_PERIOD, iperf_parallel, start_and_attach, stop TINY_DURATION = 10 SHORT_DURATION = 20 @@ -387,6 +387,7 @@ def test_zmq_2x2_mimo( enable_dddsu=True, nof_antennas_dl=2, nof_antennas_ul=2, + inter_ue_start_period=1.5, # Due to uesim ) @@ -679,6 +680,7 @@ def _iperf( enable_dddsu: bool = False, nof_antennas_dl: int = 1, nof_antennas_ul: int = 1, + inter_ue_start_period=INTER_UE_START_PERIOD, ): wait_before_power_off = 5 @@ -705,7 +707,9 @@ def _iperf( always_download_artifacts=always_download_artifacts, ) - ue_attach_info_dict = start_and_attach(ue_array, gnb, fivegc, gnb_post_cmd=gnb_post_cmd, plmn=plmn) + ue_attach_info_dict = start_and_attach( + ue_array, gnb, fivegc, gnb_post_cmd=gnb_post_cmd, plmn=plmn, inter_ue_start_period=inter_ue_start_period + ) iperf_parallel( ue_attach_info_dict, diff --git a/tests/e2e/tests/steps/stub.py b/tests/e2e/tests/steps/stub.py index 5d46aecc99..e46e45429c 100644 --- a/tests/e2e/tests/steps/stub.py +++ b/tests/e2e/tests/steps/stub.py @@ -47,6 +47,7 @@ GNB_STARTUP_TIMEOUT: int = 2 # GNB delay (we wait x seconds and check it's still alive). UE later and has a big timeout FIVEGC_STARTUP_TIMEOUT: int = RF_MAX_TIMEOUT ATTACH_TIMEOUT: int = 90 +INTER_UE_START_PERIOD: int = 0 # pylint: disable=too-many-arguments,too-many-locals @@ -61,6 +62,7 @@ def start_and_attach( gnb_post_cmd: Tuple[str, ...] = tuple(), attach_timeout: int = ATTACH_TIMEOUT, plmn: Optional[PLMN] = None, + inter_ue_start_period=INTER_UE_START_PERIOD, ) -> Dict[UEStub, UEAttachedInfo]: """ Start stubs & wait until attach @@ -82,6 +84,7 @@ def start_and_attach( fivegc, ue_startup_timeout=ue_startup_timeout, attach_timeout=attach_timeout, + inter_ue_start_period=inter_ue_start_period, ) @@ -162,6 +165,7 @@ def ue_start_and_attach( fivegc: FiveGCStub, ue_startup_timeout: int = UE_STARTUP_TIMEOUT, attach_timeout: int = ATTACH_TIMEOUT, + inter_ue_start_period: int = INTER_UE_START_PERIOD, ) -> Dict[UEStub, UEAttachedInfo]: """ Start an array of UEs and wait until attached to already running gnb and 5gc @@ -176,6 +180,7 @@ def ue_start_and_attach( start_info=StartInfo(timeout=ue_startup_timeout), ) ) + sleep(inter_ue_start_period) # Attach in parallel ue_attach_task_dict: Dict[UEStub, grpc.Future] = { From e8bd3f6d2898aaff9197349bb2d002587e2a3092 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 29 Aug 2024 10:49:35 +0200 Subject: [PATCH 053/174] phy: move PDSCH to subdirectory phy: updated PDSCH test data fix compilation phy: fix HW PDSCH encoder phy: review PDSCH related --- .../srsran/fapi_adaptor/phy/messages/pdsch.h | 2 +- .../channel_processor_factories.h | 79 --- .../channel_processor_formatters.h | 78 --- .../channel_processors/pdsch/factories.h | 101 ++++ .../channel_processors/pdsch/formatters.h | 95 ++++ .../{ => pdsch}/pdsch_encoder.h | 0 .../{ => pdsch}/pdsch_modulator.h | 0 .../{ => pdsch}/pdsch_processor.h | 19 + include/srsran/phy/upper/downlink_processor.h | 2 +- lib/fapi_adaptor/phy/fapi_to_phy_translator.h | 2 +- .../upper/channel_processors/CMakeLists.txt | 21 +- .../channel_processor_factories.cpp | 489 +----------------- .../channel_processors/pdsch/CMakeLists.txt | 20 + .../channel_processors/pdsch/factories.cpp | 427 +++++++++++++++ .../pdsch/logging_pdsch_processor_decorator.h | 102 ++++ .../{ => pdsch}/pdsch_codeblock_processor.cpp | 0 .../{ => pdsch}/pdsch_codeblock_processor.h | 0 .../{ => pdsch}/pdsch_encoder_hw_impl.cpp | 0 .../{ => pdsch}/pdsch_encoder_hw_impl.h | 2 +- .../{ => pdsch}/pdsch_encoder_impl.cpp | 0 .../{ => pdsch}/pdsch_encoder_impl.h | 2 +- .../{ => pdsch}/pdsch_modulator_impl.cpp | 0 .../{ => pdsch}/pdsch_modulator_impl.h | 2 +- .../pdsch_processor_asynchronous_pool.h | 9 +- .../pdsch_processor_concurrent_impl.cpp | 103 +++- .../pdsch_processor_concurrent_impl.h | 12 +- .../{ => pdsch}/pdsch_processor_impl.cpp | 0 .../{ => pdsch}/pdsch_processor_impl.h | 6 +- .../{ => pdsch}/pdsch_processor_lite_impl.cpp | 0 .../{ => pdsch}/pdsch_processor_lite_impl.h | 4 +- .../{ => pdsch}/pdsch_processor_pool.h | 2 +- .../pdsch_processor_validator_impl.cpp | 0 .../pdsch_processor_validator_impl.h | 2 +- ...ownlink_processor_single_executor_impl.cpp | 1 + ...downlink_processor_single_executor_state.h | 1 + lib/phy/upper/upper_phy_factories.cpp | 1 + .../pdsch_encoder_hwacc_benchmark.cpp | 3 +- .../pdsch_processor_benchmark.cpp | 52 +- .../channel_processors/pxsch_bler_test.cpp | 1 + .../pxsch_bler_test_factories.h | 2 +- .../channel_processors/pxsch_chain_test.cpp | 3 +- .../upper/channel_processors/CMakeLists.txt | 43 +- .../channel_processors/pdsch/CMakeLists.txt | 54 ++ .../{ => pdsch}/pdsch_encoder_test.cpp | 2 +- .../{ => pdsch}/pdsch_encoder_test_data.h | 2 +- .../pdsch_encoder_test_data.tar.gz | 0 .../{ => pdsch}/pdsch_encoder_test_doubles.h | 4 +- .../{ => pdsch}/pdsch_modulator_test.cpp | 6 +- .../{ => pdsch}/pdsch_modulator_test_data.h | 6 +- .../pdsch_modulator_test_data.tar.gz | 0 .../pdsch_modulator_test_doubles.h | 2 +- .../{ => pdsch}/pdsch_processor_test_data.h | 54 +- .../pdsch/pdsch_processor_test_data.tar.gz | 3 + .../pdsch_processor_test_doubles.h | 2 +- .../{ => pdsch}/pdsch_processor_unittest.cpp | 10 +- .../pdsch_processor_validator_test.cpp | 57 +- .../pdsch_processor_vectortest.cpp | 6 +- .../pdsch_processor_test_data.tar.gz | 3 - .../phy/upper/downlink_processor_test.cpp | 2 +- 59 files changed, 1070 insertions(+), 831 deletions(-) create mode 100644 include/srsran/phy/upper/channel_processors/pdsch/factories.h create mode 100644 include/srsran/phy/upper/channel_processors/pdsch/formatters.h rename include/srsran/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder.h (100%) rename include/srsran/phy/upper/channel_processors/{ => pdsch}/pdsch_modulator.h (100%) rename include/srsran/phy/upper/channel_processors/{ => pdsch}/pdsch_processor.h (90%) create mode 100644 lib/phy/upper/channel_processors/pdsch/CMakeLists.txt create mode 100644 lib/phy/upper/channel_processors/pdsch/factories.cpp create mode 100644 lib/phy/upper/channel_processors/pdsch/logging_pdsch_processor_decorator.h rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_codeblock_processor.cpp (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_codeblock_processor.h (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_hw_impl.cpp (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_hw_impl.h (98%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_impl.cpp (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_impl.h (97%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_modulator_impl.cpp (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_modulator_impl.h (97%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_asynchronous_pool.h (94%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_concurrent_impl.cpp (76%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_concurrent_impl.h (90%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_impl.cpp (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_impl.h (94%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_lite_impl.cpp (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_lite_impl.h (97%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_pool.h (96%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_validator_impl.cpp (100%) rename lib/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_validator_impl.h (90%) create mode 100644 tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_test.cpp (99%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_test_data.h (99%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_test_data.tar.gz (100%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_encoder_test_doubles.h (91%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_modulator_test.cpp (89%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_modulator_test_data.h (98%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_modulator_test_data.tar.gz (100%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_modulator_test_doubles.h (92%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_test_data.h (73%) create mode 100644 tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_data.tar.gz rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_test_doubles.h (95%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_unittest.cpp (97%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_validator_test.cpp (80%) rename tests/unittests/phy/upper/channel_processors/{ => pdsch}/pdsch_processor_vectortest.cpp (98%) delete mode 100644 tests/unittests/phy/upper/channel_processors/pdsch_processor_test_data.tar.gz diff --git a/include/srsran/fapi_adaptor/phy/messages/pdsch.h b/include/srsran/fapi_adaptor/phy/messages/pdsch.h index bc9fe25b6b..bd762b2a34 100644 --- a/include/srsran/fapi_adaptor/phy/messages/pdsch.h +++ b/include/srsran/fapi_adaptor/phy/messages/pdsch.h @@ -12,7 +12,7 @@ #include "srsran/fapi/messages.h" #include "srsran/phy/support/re_pattern.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" namespace srsran { namespace fapi_adaptor { diff --git a/include/srsran/phy/upper/channel_processors/channel_processor_factories.h b/include/srsran/phy/upper/channel_processors/channel_processor_factories.h index fd5228c543..505297dd66 100644 --- a/include/srsran/phy/upper/channel_processors/channel_processor_factories.h +++ b/include/srsran/phy/upper/channel_processors/channel_processor_factories.h @@ -11,7 +11,6 @@ #pragma once #include "pucch_detector.h" -#include "srsran/hal/phy/upper/channel_processors/hw_accelerator_pdsch_enc_factory.h" #include "srsran/phy/generic_functions/generic_functions_factories.h" #include "srsran/phy/upper/channel_coding/channel_coding_factories.h" #include "srsran/phy/upper/channel_modulation/channel_modulation_factories.h" @@ -20,9 +19,6 @@ #include "srsran/phy/upper/channel_processors/pdcch_encoder.h" #include "srsran/phy/upper/channel_processors/pdcch_modulator.h" #include "srsran/phy/upper/channel_processors/pdcch_processor.h" -#include "srsran/phy/upper/channel_processors/pdsch_encoder.h" -#include "srsran/phy/upper/channel_processors/pdsch_modulator.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" #include "srsran/phy/upper/channel_processors/prach_detector.h" #include "srsran/phy/upper/channel_processors/prach_generator.h" #include "srsran/phy/upper/channel_processors/pucch_demodulator.h" @@ -102,81 +98,6 @@ std::shared_ptr create_pdcch_processor_pool_factory(std::shared_ptr processor_factory, unsigned nof_concurrent_threads); -class pdsch_encoder_factory -{ -public: - virtual ~pdsch_encoder_factory() = default; - virtual std::unique_ptr create() = 0; -}; - -struct pdsch_encoder_factory_sw_configuration { - std::shared_ptr encoder_factory; - std::shared_ptr rate_matcher_factory; - std::shared_ptr segmenter_factory; -}; - -std::shared_ptr create_pdsch_encoder_factory_sw(pdsch_encoder_factory_sw_configuration& config); - -/// HW-accelerated PDSCH encoder factory configuration parameters. -struct pdsch_encoder_factory_hw_configuration { - std::shared_ptr crc_factory; - std::shared_ptr segmenter_factory; - std::shared_ptr hw_encoder_factory; -}; - -std::shared_ptr -create_pdsch_encoder_factory_hw(const pdsch_encoder_factory_hw_configuration& config); - -class pdsch_modulator_factory -{ -public: - virtual ~pdsch_modulator_factory() = default; - virtual std::unique_ptr create() = 0; -}; - -std::shared_ptr - create_pdsch_modulator_factory_sw(std::shared_ptr, - std::shared_ptr); - -class pdsch_processor_factory -{ -public: - virtual ~pdsch_processor_factory() = default; - virtual std::unique_ptr create() = 0; - virtual std::unique_ptr create_validator() = 0; - virtual std::unique_ptr create(srslog::basic_logger& logger, bool enable_logging_broadcast); -}; - -std::shared_ptr -create_pdsch_processor_factory_sw(std::shared_ptr encoder_factory, - std::shared_ptr modulator_factory, - std::shared_ptr dmrs_factory); - -std::shared_ptr -create_pdsch_concurrent_processor_factory_sw(std::shared_ptr crc_factory, - std::shared_ptr ldpc_enc_factory, - std::shared_ptr ldpc_rm_factory, - std::shared_ptr prg_factory, - std::shared_ptr modulator_factory, - std::shared_ptr dmrs_factory, - task_executor& executor, - unsigned nof_concurrent_threads); - -std::shared_ptr -create_pdsch_lite_processor_factory_sw(std::shared_ptr segmenter_factory, - std::shared_ptr encoder_factory, - std::shared_ptr rate_matcher_factory, - std::shared_ptr scrambler_factory, - std::shared_ptr modulator_factory, - std::shared_ptr dmrs_factory); - -std::shared_ptr -create_pdsch_processor_asynchronous_pool(std::shared_ptr pdsch_proc_factory, - unsigned max_nof_processors); - -std::shared_ptr -create_pdsch_processor_pool(std::shared_ptr pdsch_proc_factory, unsigned max_nof_processors); - class prach_detector_factory { public: diff --git a/include/srsran/phy/upper/channel_processors/channel_processor_formatters.h b/include/srsran/phy/upper/channel_processors/channel_processor_formatters.h index 7c43be8e7d..d9cc746ae9 100644 --- a/include/srsran/phy/upper/channel_processors/channel_processor_formatters.h +++ b/include/srsran/phy/upper/channel_processors/channel_processor_formatters.h @@ -13,13 +13,11 @@ #include "srsran/phy/support/precoding_formatters.h" #include "srsran/phy/support/re_pattern_formatters.h" #include "srsran/phy/upper/channel_processors/pdcch_processor.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" #include "srsran/phy/upper/channel_processors/prach_detector.h" #include "srsran/phy/upper/channel_processors/pucch_processor.h" #include "srsran/phy/upper/channel_processors/ssb_processor.h" #include "srsran/phy/upper/channel_state_information_formatters.h" #include "srsran/ran/pdcch/pdcch_context_formatter.h" -#include "srsran/ran/pdsch/pdsch_context_formatter.h" #include "srsran/ran/pucch/pucch_context_formatter.h" #include "srsran/srsvec/copy.h" #include "srsran/support/format_utils.h" @@ -109,82 +107,6 @@ struct formatter { } }; -/// \brief Custom formatter for \c pdsch_processor::codeword_description. -template <> -struct formatter { - /// Helper used to parse formatting options and format fields. - srsran::delimited_formatter helper; - - /// Default constructor. - formatter() = default; - - template - auto parse(ParseContext& ctx) -> decltype(ctx.begin()) - { - return helper.parse(ctx); - } - - template - auto format(const srsran::pdsch_processor::codeword_description& codeword_descr, FormatContext& ctx) - -> decltype(std::declval().out()) - { - helper.format_always(ctx, "mod={}", to_string(codeword_descr.modulation)); - helper.format_always(ctx, "rv={}", codeword_descr.rv); - - return ctx.out(); - } -}; - -/// \brief Custom formatter for \c pdsch_processor::pdu_t. -template <> -struct formatter { - /// Helper used to parse formatting options and format fields. - srsran::delimited_formatter helper; - - /// Default constructor. - formatter() = default; - - template - auto parse(ParseContext& ctx) -> decltype(ctx.begin()) - { - return helper.parse(ctx); - } - - template - auto format(const srsran::pdsch_processor::pdu_t& pdu, FormatContext& ctx) - -> decltype(std::declval().out()) - { - helper.format_always(ctx, "rnti=0x{:04x}", pdu.rnti); - if (pdu.context.has_value()) { - helper.format_always(ctx, pdu.context.value()); - } - helper.format_if_verbose(ctx, "bwp=[{}, {})", pdu.bwp_start_rb, pdu.bwp_start_rb + pdu.bwp_size_rb); - helper.format_always(ctx, "prb={}", pdu.freq_alloc); - helper.format_always(ctx, "symb=[{}, {})", pdu.start_symbol_index, pdu.start_symbol_index + pdu.nof_symbols); - helper.format_always(ctx, srsran::span(pdu.codewords)); - - helper.format_if_verbose(ctx, "n_id={}", pdu.n_id); - helper.format_if_verbose( - ctx, "ref_point={}", (pdu.ref_point == srsran::pdsch_processor::pdu_t::CRB0) ? "CRB0" : "PRB0"); - helper.format_if_verbose(ctx, "dmrs_type={}", (pdu.dmrs == srsran::dmrs_type::TYPE1) ? 1 : 2); - helper.format_if_verbose(ctx, "dmrs_mask={}", pdu.dmrs_symbol_mask); - helper.format_if_verbose(ctx, "n_scidid={}", pdu.scrambling_id); - helper.format_if_verbose(ctx, "n_scid={}", pdu.n_scid); - helper.format_if_verbose(ctx, "ncgwd={}", pdu.nof_cdm_groups_without_data); - helper.format_if_verbose(ctx, "bg={}", (pdu.ldpc_base_graph == srsran::ldpc_base_graph_type::BG1) ? "BG1" : "BG2"); - helper.format_if_verbose(ctx, "tbs_lbrm={}bytes", pdu.tbs_lbrm); - helper.format_if_verbose(ctx, "power_dmrs={:+.1f}dB", -pdu.ratio_pdsch_dmrs_to_sss_dB); - helper.format_if_verbose(ctx, "power_data={:+.1f}dB", pdu.ratio_pdsch_data_to_sss_dB); - helper.format_if_verbose(ctx, "slot={}", pdu.slot); - helper.format_if_verbose(ctx, "cp={}", pdu.cp.to_string()); - helper.format_if_verbose(ctx, "precoding={}", pdu.precoding); - if (pdu.reserved.get_nof_entries() > 0) { - helper.format_if_verbose(ctx, "reserved=[{:,}]", pdu.reserved.get_re_patterns()); - } - return ctx.out(); - } -}; - /// \brief Custom formatter for \c prach_detector::configuration. template <> struct formatter { diff --git a/include/srsran/phy/upper/channel_processors/pdsch/factories.h b/include/srsran/phy/upper/channel_processors/pdsch/factories.h new file mode 100644 index 0000000000..80db1b3856 --- /dev/null +++ b/include/srsran/phy/upper/channel_processors/pdsch/factories.h @@ -0,0 +1,101 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/hal/phy/upper/channel_processors/hw_accelerator_pdsch_enc_factory.h" +#include "srsran/phy/upper/channel_coding/channel_coding_factories.h" +#include "srsran/phy/upper/channel_modulation/channel_modulation_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_modulator.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" +#include "srsran/phy/upper/sequence_generators/sequence_generator_factories.h" +#include "srsran/phy/upper/signal_processors/signal_processor_factories.h" +#include "srsran/support/executors/task_executor.h" +#include + +namespace srsran { + +class pdsch_encoder_factory +{ +public: + virtual ~pdsch_encoder_factory() = default; + virtual std::unique_ptr create() = 0; +}; + +struct pdsch_encoder_factory_sw_configuration { + std::shared_ptr encoder_factory; + std::shared_ptr rate_matcher_factory; + std::shared_ptr segmenter_factory; +}; + +std::shared_ptr create_pdsch_encoder_factory_sw(pdsch_encoder_factory_sw_configuration& config); + +/// HW-accelerated PDSCH encoder factory configuration parameters. +struct pdsch_encoder_factory_hw_configuration { + std::shared_ptr crc_factory; + std::shared_ptr segmenter_factory; + std::shared_ptr hw_encoder_factory; +}; + +std::shared_ptr +create_pdsch_encoder_factory_hw(const pdsch_encoder_factory_hw_configuration& config); + +class pdsch_modulator_factory +{ +public: + virtual ~pdsch_modulator_factory() = default; + virtual std::unique_ptr create() = 0; +}; + +std::shared_ptr + create_pdsch_modulator_factory_sw(std::shared_ptr, + std::shared_ptr); + +class pdsch_processor_factory +{ +public: + virtual ~pdsch_processor_factory() = default; + virtual std::unique_ptr create() = 0; + virtual std::unique_ptr create_validator() = 0; + virtual std::unique_ptr create(srslog::basic_logger& logger, bool enable_logging_broadcast); +}; + +std::shared_ptr +create_pdsch_processor_factory_sw(std::shared_ptr encoder_factory, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory); + +std::shared_ptr +create_pdsch_concurrent_processor_factory_sw(std::shared_ptr crc_factory, + std::shared_ptr ldpc_enc_factory, + std::shared_ptr ldpc_rm_factory, + std::shared_ptr prg_factory, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory, + task_executor& executor, + unsigned nof_concurrent_threads); + +std::shared_ptr +create_pdsch_lite_processor_factory_sw(std::shared_ptr segmenter_factory, + std::shared_ptr encoder_factory, + std::shared_ptr rate_matcher_factory, + std::shared_ptr scrambler_factory, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory); + +std::shared_ptr +create_pdsch_processor_asynchronous_pool(std::shared_ptr pdsch_proc_factory, + unsigned max_nof_processors); + +std::shared_ptr +create_pdsch_processor_pool(std::shared_ptr pdsch_proc_factory, unsigned max_nof_processors); + +} // namespace srsran \ No newline at end of file diff --git a/include/srsran/phy/upper/channel_processors/pdsch/formatters.h b/include/srsran/phy/upper/channel_processors/pdsch/formatters.h new file mode 100644 index 0000000000..1687030ee7 --- /dev/null +++ b/include/srsran/phy/upper/channel_processors/pdsch/formatters.h @@ -0,0 +1,95 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" +#include "srsran/ran/pdsch/pdsch_context_formatter.h" +#include "srsran/support/format_utils.h" + +namespace fmt { + +/// \brief Custom formatter for \c pdsch_processor::codeword_description. +template <> +struct formatter { + /// Helper used to parse formatting options and format fields. + srsran::delimited_formatter helper; + + /// Default constructor. + formatter() = default; + + template + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) + { + return helper.parse(ctx); + } + + template + auto format(const srsran::pdsch_processor::codeword_description& codeword_descr, FormatContext& ctx) + -> decltype(std::declval().out()) + { + helper.format_always(ctx, "mod={}", to_string(codeword_descr.modulation)); + helper.format_always(ctx, "rv={}", codeword_descr.rv); + + return ctx.out(); + } +}; + +/// \brief Custom formatter for \c pdsch_processor::pdu_t. +template <> +struct formatter { + /// Helper used to parse formatting options and format fields. + srsran::delimited_formatter helper; + + /// Default constructor. + formatter() = default; + + template + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) + { + return helper.parse(ctx); + } + + template + auto format(const srsran::pdsch_processor::pdu_t& pdu, FormatContext& ctx) + -> decltype(std::declval().out()) + { + helper.format_always(ctx, "rnti=0x{:04x}", pdu.rnti); + if (pdu.context.has_value()) { + helper.format_always(ctx, pdu.context.value()); + } + helper.format_if_verbose(ctx, "bwp=[{}, {})", pdu.bwp_start_rb, pdu.bwp_start_rb + pdu.bwp_size_rb); + helper.format_always(ctx, "prb={}", pdu.freq_alloc); + helper.format_always(ctx, "symb=[{}, {})", pdu.start_symbol_index, pdu.start_symbol_index + pdu.nof_symbols); + helper.format_always(ctx, srsran::span(pdu.codewords)); + + helper.format_if_verbose(ctx, "n_id={}", pdu.n_id); + helper.format_if_verbose( + ctx, "ref_point={}", (pdu.ref_point == srsran::pdsch_processor::pdu_t::CRB0) ? "CRB0" : "PRB0"); + helper.format_if_verbose(ctx, "dmrs_type={}", (pdu.dmrs == srsran::dmrs_type::TYPE1) ? 1 : 2); + helper.format_if_verbose(ctx, "dmrs_mask={}", pdu.dmrs_symbol_mask); + helper.format_if_verbose(ctx, "n_scidid={}", pdu.scrambling_id); + helper.format_if_verbose(ctx, "n_scid={}", pdu.n_scid); + helper.format_if_verbose(ctx, "ncgwd={}", pdu.nof_cdm_groups_without_data); + helper.format_if_verbose(ctx, "bg={}", (pdu.ldpc_base_graph == srsran::ldpc_base_graph_type::BG1) ? "BG1" : "BG2"); + helper.format_if_verbose(ctx, "tbs_lbrm={}bytes", pdu.tbs_lbrm); + helper.format_if_verbose(ctx, "power_dmrs={:+.1f}dB", -pdu.ratio_pdsch_dmrs_to_sss_dB); + helper.format_if_verbose(ctx, "power_data={:+.1f}dB", pdu.ratio_pdsch_data_to_sss_dB); + helper.format_if_verbose(ctx, "slot={}", pdu.slot); + helper.format_if_verbose(ctx, "cp={}", pdu.cp.to_string()); + helper.format_if_verbose(ctx, "precoding={}", pdu.precoding); + if (pdu.reserved.get_nof_entries() > 0) { + helper.format_if_verbose(ctx, "reserved=[{:,}]", pdu.reserved.get_re_patterns()); + } + return ctx.out(); + } +}; + +} // namespace fmt diff --git a/include/srsran/phy/upper/channel_processors/pdsch_encoder.h b/include/srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h similarity index 100% rename from include/srsran/phy/upper/channel_processors/pdsch_encoder.h rename to include/srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h diff --git a/include/srsran/phy/upper/channel_processors/pdsch_modulator.h b/include/srsran/phy/upper/channel_processors/pdsch/pdsch_modulator.h similarity index 100% rename from include/srsran/phy/upper/channel_processors/pdsch_modulator.h rename to include/srsran/phy/upper/channel_processors/pdsch/pdsch_modulator.h diff --git a/include/srsran/phy/upper/channel_processors/pdsch_processor.h b/include/srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h similarity index 90% rename from include/srsran/phy/upper/channel_processors/pdsch_processor.h rename to include/srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h index 6e1bb2a654..4895d47016 100644 --- a/include/srsran/phy/upper/channel_processors/pdsch_processor.h +++ b/include/srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h @@ -18,6 +18,7 @@ #include "srsran/phy/upper/dmrs_mapping.h" #include "srsran/phy/upper/rb_allocation.h" #include "srsran/ran/pdsch/pdsch_context.h" +#include "srsran/ran/ptrs/ptrs.h" #include "srsran/ran/sch/modulation_scheme.h" #include "srsran/ran/slot_point.h" @@ -50,6 +51,20 @@ class pdsch_processor unsigned rv; }; + /// Parameters for the Phase Tracking Reference Signals (PT-RS). + struct ptrs_configuration { + /// Frequency domain density. + ptrs_frequency_density freq_density; + /// Time domain density. + ptrs_time_density time_density; + /// Resource element offset. + ptrs_re_offset re_offset; + /// \brief Ratio of PT-RS EPRE to PDSCH data EPRE in decibels. + /// + /// Parameter \f$\rho_{PTRS}f$ as per TS38.214 Section 4.1. + float ratio_ptrs_to_pdsch_data_dB; + }; + /// \brief Describes the PDSCH processing parameters. struct pdu_t { /// Context information. @@ -130,6 +145,10 @@ class pdsch_processor units::bytes tbs_lbrm; /// Indicates the reserved resource elements which cannot carry PDSCH. re_pattern_list reserved; + /// \brief Optional Phase Tracking Reference Signal (PT-RS) configuration. + /// + /// Set to \c std::nullopt for no transmission of PT-RS. + std::optional ptrs; /// \brief Ratio of PDSCH DM-RS EPRE to SSS EPRE in decibels. /// /// Parameter \f$\beta _\textup{DMRS}\f$ in TS38.214 Section 6.2.2. It is converted to parameter \f$\beta _{PUSCH} diff --git a/include/srsran/phy/upper/downlink_processor.h b/include/srsran/phy/upper/downlink_processor.h index e8f227963f..33bcd916e5 100644 --- a/include/srsran/phy/upper/downlink_processor.h +++ b/include/srsran/phy/upper/downlink_processor.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/phy/upper/channel_processors/pdcch_processor.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/phy/upper/channel_processors/ssb_processor.h" #include "srsran/phy/upper/signal_processors/nzp_csi_rs_generator.h" diff --git a/lib/fapi_adaptor/phy/fapi_to_phy_translator.h b/lib/fapi_adaptor/phy/fapi_to_phy_translator.h index 2eaa8fe35a..72c85433c4 100644 --- a/lib/fapi_adaptor/phy/fapi_to_phy_translator.h +++ b/lib/fapi_adaptor/phy/fapi_to_phy_translator.h @@ -15,7 +15,7 @@ #include "srsran/fapi/slot_message_gateway.h" #include "srsran/fapi_adaptor/precoding_matrix_repository.h" #include "srsran/fapi_adaptor/uci_part2_correspondence_repository.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/srslog/logger.h" #include "srsran/support/executors/task_executor.h" #include diff --git a/lib/phy/upper/channel_processors/CMakeLists.txt b/lib/phy/upper/channel_processors/CMakeLists.txt index f7fe45adc6..fd24aa6679 100644 --- a/lib/phy/upper/channel_processors/CMakeLists.txt +++ b/lib/phy/upper/channel_processors/CMakeLists.txt @@ -6,6 +6,7 @@ # the distribution. # +add_subdirectory(pdsch) add_subdirectory(pusch) add_subdirectory(uci) @@ -24,22 +25,6 @@ target_link_libraries(srsran_pdcch_modulator srsvec) add_library(srsran_pdcch_processor STATIC pdcch_processor_impl.cpp) target_link_libraries(srsran_pdcch_processor srsran_ran) -add_library(srsran_pdsch_encoder STATIC - pdsch_encoder_impl.cpp - pdsch_encoder_hw_impl.cpp) -target_link_libraries(srsran_pdsch_encoder srsran_channel_coding) - -add_library(srsran_pdsch_modulator STATIC pdsch_modulator_impl.cpp) -target_link_libraries(srsran_pdsch_modulator srsran_channel_modulation srsran_sequence_generators srsvec srsran_upper_phy_support) - -add_library(srsran_pdsch_processor STATIC - pdsch_codeblock_processor.cpp - pdsch_processor_concurrent_impl.cpp - pdsch_processor_impl.cpp - pdsch_processor_lite_impl.cpp - pdsch_processor_validator_impl.cpp) -target_link_libraries(srsran_pdsch_processor srsran_upper_phy_support srsran_channel_modulation) - add_library(srsran_prach_detector STATIC prach_detector_generic_impl.cpp prach_generator_impl.cpp @@ -64,8 +49,6 @@ target_link_libraries(srsran_channel_processors srsran_pdcch_encoder srsran_pdcch_modulator srsran_pdcch_processor - srsran_pdsch_encoder - srsran_pdsch_modulator srsran_pdsch_processor srsran_prach_detector srsran_pucch_demodulator @@ -81,8 +64,6 @@ add_to_exported_libs(srsran_channel_processors srsran_pdcch_encoder srsran_pdcch_modulator srsran_pdcch_processor - srsran_pdsch_encoder - srsran_pdsch_modulator srsran_pdsch_processor srsran_prach_detector srsran_pucch_demodulator diff --git a/lib/phy/upper/channel_processors/channel_processor_factories.cpp b/lib/phy/upper/channel_processors/channel_processor_factories.cpp index 1e5c658d07..4290bfed44 100644 --- a/lib/phy/upper/channel_processors/channel_processor_factories.cpp +++ b/lib/phy/upper/channel_processors/channel_processor_factories.cpp @@ -15,15 +15,6 @@ #include "pdcch_modulator_impl.h" #include "pdcch_processor_impl.h" #include "pdcch_processor_pool.h" -#include "pdsch_encoder_hw_impl.h" -#include "pdsch_encoder_impl.h" -#include "pdsch_modulator_impl.h" -#include "pdsch_processor_asynchronous_pool.h" -#include "pdsch_processor_concurrent_impl.h" -#include "pdsch_processor_impl.h" -#include "pdsch_processor_lite_impl.h" -#include "pdsch_processor_pool.h" -#include "pdsch_processor_validator_impl.h" #include "prach_detector_generic_impl.h" #include "prach_detector_pool.h" #include "prach_generator_impl.h" @@ -35,6 +26,7 @@ #include "ssb_processor_pool.h" #include "srsran/phy/support/support_formatters.h" #include "srsran/phy/upper/channel_modulation/channel_modulation_factories.h" +#include "srsran/phy/upper/channel_processors/channel_processor_formatters.h" #include "srsran/phy/upper/sequence_generators/sequence_generator_factories.h" #include "srsran/srsvec/bit.h" #include "srsran/srsvec/zero.h" @@ -161,7 +153,7 @@ class pdcch_processor_factory_sw : public pdcch_processor_factory { srsran_assert(encoder_factory, "Invalid encoder factory."); srsran_assert(modulator_factory, "Invalid modulator factory."); - srsran_assert(dmrs_factory, "Invalid DMRS factory."); + srsran_assert(dmrs_factory, "Invalid DM-RS factory."); } std::unique_ptr create() override @@ -224,320 +216,6 @@ class pdcch_processor_pool_factory : public pdcch_processor_factory std::shared_ptr processors; }; -class pdsch_encoder_factory_sw : public pdsch_encoder_factory -{ -private: - std::shared_ptr encoder_factory; - std::shared_ptr rate_matcher_factory; - std::shared_ptr segmenter_factory; - -public: - explicit pdsch_encoder_factory_sw(pdsch_encoder_factory_sw_configuration& config) : - encoder_factory(std::move(config.encoder_factory)), - rate_matcher_factory(std::move(config.rate_matcher_factory)), - segmenter_factory(std::move(config.segmenter_factory)) - { - srsran_assert(encoder_factory, "Invalid LDPC encoder factory."); - srsran_assert(rate_matcher_factory, "Invalid LDPC RM factory."); - srsran_assert(segmenter_factory, "Invalid LDPC segmenter factory."); - } - - std::unique_ptr create() override - { - return std::make_unique( - segmenter_factory->create(), encoder_factory->create(), rate_matcher_factory->create()); - } -}; - -/// HW-accelerated PDSCH encoder factory. -class pdsch_encoder_factory_hw : public pdsch_encoder_factory -{ -private: - std::shared_ptr crc_factory; - std::shared_ptr segmenter_factory; - std::shared_ptr hw_encoder_factory; - -public: - explicit pdsch_encoder_factory_hw(const pdsch_encoder_factory_hw_configuration& config) : - crc_factory(std::move(config.crc_factory)), - segmenter_factory(std::move(config.segmenter_factory)), - hw_encoder_factory(std::move(config.hw_encoder_factory)) - { - srsran_assert(crc_factory, "Invalid CRC factory."); - srsran_assert(segmenter_factory, "Invalid LDPC segmenter factory."); - srsran_assert(hw_encoder_factory, "Invalid hardware accelerator factory."); - } - - std::unique_ptr create() override - { - pdsch_encoder_hw_impl::sch_crc crc = { - crc_factory->create(crc_generator_poly::CRC16), - crc_factory->create(crc_generator_poly::CRC24A), - crc_factory->create(crc_generator_poly::CRC24B), - }; - return std::make_unique(crc, segmenter_factory->create(), hw_encoder_factory->create()); - } -}; - -class pdsch_modulator_factory_sw : public pdsch_modulator_factory -{ -private: - std::shared_ptr modulator_factory; - std::shared_ptr prg_factory; - -public: - pdsch_modulator_factory_sw(std::shared_ptr modulator_factory_, - std::shared_ptr prg_factory_) : - modulator_factory(std::move(modulator_factory_)), prg_factory(std::move(prg_factory_)) - { - srsran_assert(modulator_factory, "Invalid modulator factory."); - srsran_assert(prg_factory, "Invalid PRG factory."); - } - - std::unique_ptr create() override - { - return std::make_unique(modulator_factory->create_modulation_mapper(), prg_factory->create()); - } -}; - -class pdsch_processor_factory_sw : public pdsch_processor_factory -{ -private: - std::shared_ptr encoder_factory; - std::shared_ptr modulator_factory; - std::shared_ptr dmrs_factory; - -public: - pdsch_processor_factory_sw(std::shared_ptr encoder_factory_, - std::shared_ptr modulator_factory_, - std::shared_ptr dmrs_factory_) : - encoder_factory(std::move(encoder_factory_)), - modulator_factory(std::move(modulator_factory_)), - dmrs_factory(std::move(dmrs_factory_)) - { - srsran_assert(encoder_factory, "Invalid encoder factory."); - srsran_assert(modulator_factory, "Invalid modulator factory."); - srsran_assert(dmrs_factory, "Invalid DMRS factory."); - } - - std::unique_ptr create() override - { - return std::make_unique( - encoder_factory->create(), modulator_factory->create(), dmrs_factory->create()); - } - - std::unique_ptr create_validator() override - { - return std::make_unique(); - } -}; - -class pdsch_processor_concurrent_factory_sw : public pdsch_processor_factory -{ -public: - pdsch_processor_concurrent_factory_sw(std::shared_ptr crc_factory, - std::shared_ptr encoder_factory, - std::shared_ptr rate_matcher_factory, - std::shared_ptr prg_factory_, - std::shared_ptr modulator_factory, - std::shared_ptr dmrs_factory, - task_executor& executor_, - unsigned nof_concurrent_threads) : - prg_factory(std::move(prg_factory_)), executor(executor_) - { - srsran_assert(crc_factory, "Invalid CRC calculator factory."); - srsran_assert(encoder_factory, "Invalid encoder factory."); - srsran_assert(rate_matcher_factory, "Invalid rate matcher factory."); - srsran_assert(prg_factory, "Invalid PRG factory."); - srsran_assert(modulator_factory, "Invalid modulator factory."); - srsran_assert(dmrs_factory, "Invalid DM-RS factory."); - - // Create vector of codeblock processors. - std::vector> cb_processors; - for (unsigned i_encoder = 0; i_encoder != nof_concurrent_threads; ++i_encoder) { - cb_processors.emplace_back( - std::make_unique(crc_factory->create(crc_generator_poly::CRC24A), - crc_factory->create(crc_generator_poly::CRC24B), - crc_factory->create(crc_generator_poly::CRC16), - encoder_factory->create(), - rate_matcher_factory->create(), - prg_factory->create(), - modulator_factory->create_modulation_mapper())); - } - - // Create pool of codeblock processors. It is common for all PDSCH processors. - cb_processor_pool = - std::make_shared(std::move(cb_processors)); - - // Create vector of PDSCH DM-RS generators. - std::vector> dmrs_generators; - for (unsigned i_encoder = 0; i_encoder != nof_concurrent_threads; ++i_encoder) { - dmrs_generators.emplace_back(dmrs_factory->create()); - } - - // Create pool of PDSCH DM-RS generators. It is common for all PDSCH processors. - dmrs_generator_pool = - std::make_shared(std::move(dmrs_generators)); - } - - std::unique_ptr create() override - { - return std::make_unique( - cb_processor_pool, prg_factory->create(), dmrs_generator_pool, executor); - } - - std::unique_ptr create_validator() override - { - return std::make_unique(); - } - -private: - std::shared_ptr prg_factory; - task_executor& executor; - std::shared_ptr cb_processor_pool; - std::shared_ptr dmrs_generator_pool; -}; - -class pdsch_processor_lite_factory_sw : public pdsch_processor_factory -{ -private: - std::shared_ptr segmenter_factory; - std::shared_ptr encoder_factory; - std::shared_ptr rate_matcher_factory; - std::shared_ptr scrambler_factory; - std::shared_ptr modulator_factory; - std::shared_ptr dmrs_factory; - -public: - pdsch_processor_lite_factory_sw(std::shared_ptr segmenter_factory_, - std::shared_ptr encoder_factory_, - std::shared_ptr rate_matcher_factory_, - std::shared_ptr scrambler_factory_, - std::shared_ptr modulator_factory_, - std::shared_ptr dmrs_factory_) : - segmenter_factory(std::move(segmenter_factory_)), - encoder_factory(std::move(encoder_factory_)), - rate_matcher_factory(std::move(rate_matcher_factory_)), - scrambler_factory(std::move(scrambler_factory_)), - modulator_factory(std::move(modulator_factory_)), - dmrs_factory(std::move(dmrs_factory_)) - { - srsran_assert(segmenter_factory, "Invalid segmenter factory."); - srsran_assert(encoder_factory, "Invalid encoder factory."); - srsran_assert(rate_matcher_factory, "Invalid rate matcher factory."); - srsran_assert(scrambler_factory, "Invalid scrambler factory."); - srsran_assert(modulator_factory, "Invalid modulator factory."); - srsran_assert(dmrs_factory, "Invalid DM-RS factory."); - } - - std::unique_ptr create() override - { - return std::make_unique(segmenter_factory->create(), - encoder_factory->create(), - rate_matcher_factory->create(), - scrambler_factory->create(), - modulator_factory->create_modulation_mapper(), - dmrs_factory->create()); - } - - std::unique_ptr create_validator() override - { - return std::make_unique(); - } -}; - -class pdsch_processor_asynchronous_pool_factory : public pdsch_processor_factory -{ -public: - pdsch_processor_asynchronous_pool_factory(std::shared_ptr factory_, - unsigned max_nof_processors_) : - factory(std::move(factory_)), max_nof_processors(max_nof_processors_) - { - srsran_assert(factory, "Invalid PDSCH processor factory."); - srsran_assert(max_nof_processors >= 1, - "The number of processors (i.e., {}) must be greater than or equal to one.", - max_nof_processors); - } - - std::unique_ptr create() override - { - // Create processors. - std::vector> processors(max_nof_processors); - for (std::unique_ptr& processor : processors) { - processor = factory->create(); - } - - return std::make_unique(processors, false); - } - - std::unique_ptr create(srslog::basic_logger& logger, bool enable_logging_broadcast) override - { - // Create processors with logging. - std::vector> processors(max_nof_processors); - for (std::unique_ptr& processor : processors) { - processor = factory->create(logger, enable_logging_broadcast); - } - - return std::make_unique(processors, false); - } - - std::unique_ptr create_validator() override { return factory->create_validator(); } - -private: - std::shared_ptr factory; - unsigned max_nof_processors; -}; - -class pdsch_processor_pool_factory : public pdsch_processor_factory -{ -public: - pdsch_processor_pool_factory(std::shared_ptr factory_, unsigned max_nof_processors_) : - factory(std::move(factory_)), max_nof_processors(max_nof_processors_) - { - srsran_assert(factory, "Invalid PDSCH processor factory."); - srsran_assert(max_nof_processors != 0, "The number of processors must not be zero."); - } - - std::unique_ptr create() override - { - // Creates the processors without logging. - if (!processors) { - // Create PDSCH processsor instances. - std::vector> instances(max_nof_processors); - std::generate(instances.begin(), instances.end(), [this]() { return factory->create(); }); - - // Create pool. - processors = std::make_shared(std::move(instances)); - } - - return std::make_unique(processors); - } - - std::unique_ptr create(srslog::basic_logger& logger, bool enable_logging_broadcast) override - { - // Creates the processors with logging. - if (!processors) { - // Create PDSCH processor instances. - std::vector> instances(max_nof_processors); - std::generate(instances.begin(), instances.end(), [this, &logger, &enable_logging_broadcast]() { - return factory->create(logger, enable_logging_broadcast); - }); - - // Create pool. - processors = std::make_shared(std::move(instances)); - } - - return std::make_unique(processors); - } - - std::unique_ptr create_validator() override { return factory->create_validator(); } - -private: - std::shared_ptr factory; - std::shared_ptr processors; - unsigned max_nof_processors; -}; - class prach_detector_factory_sw : public prach_detector_factory { private: @@ -930,84 +608,6 @@ srsran::create_pdcch_processor_pool_factory(std::shared_ptr(processor_factory, nof_concurrent_threads); } -std::shared_ptr -srsran::create_pdsch_encoder_factory_sw(pdsch_encoder_factory_sw_configuration& config) -{ - return std::make_shared(config); -} - -std::shared_ptr -srsran::create_pdsch_encoder_factory_hw(const pdsch_encoder_factory_hw_configuration& config) -{ - return std::make_shared(config); -} - -std::shared_ptr -srsran::create_pdsch_modulator_factory_sw(std::shared_ptr modulator_factory, - std::shared_ptr prg_factory) -{ - return std::make_shared(std::move(modulator_factory), std::move(prg_factory)); -} - -std::shared_ptr -srsran::create_pdsch_processor_factory_sw(std::shared_ptr encoder_factory, - std::shared_ptr modulator_factory, - std::shared_ptr dmrs_factory) -{ - return std::make_shared( - std::move(encoder_factory), std::move(modulator_factory), std::move(dmrs_factory)); -} - -std::shared_ptr -srsran::create_pdsch_concurrent_processor_factory_sw(std::shared_ptr crc_factory, - std::shared_ptr ldpc_enc_factory, - std::shared_ptr ldpc_rm_factory, - std::shared_ptr prg_factory, - std::shared_ptr modulator_factory, - std::shared_ptr dmrs_factory, - task_executor& executor, - unsigned nof_concurrent_threads) -{ - return std::make_shared(std::move(crc_factory), - std::move(ldpc_enc_factory), - std::move(ldpc_rm_factory), - std::move(prg_factory), - std::move(modulator_factory), - std::move(dmrs_factory), - executor, - nof_concurrent_threads); -} - -std::shared_ptr -srsran::create_pdsch_lite_processor_factory_sw(std::shared_ptr segmenter_factory, - std::shared_ptr encoder_factory, - std::shared_ptr rate_matcher_factory, - std::shared_ptr scrambler_factory, - std::shared_ptr modulator_factory, - std::shared_ptr dmrs_factory) -{ - return std::make_shared(std::move(segmenter_factory), - std::move(encoder_factory), - std::move(rate_matcher_factory), - std::move(scrambler_factory), - std::move(modulator_factory), - std::move(dmrs_factory)); -} - -std::shared_ptr -srsran::create_pdsch_processor_asynchronous_pool(std::shared_ptr pdsch_proc_factory, - unsigned max_nof_processors) -{ - return std::make_shared(std::move(pdsch_proc_factory), max_nof_processors); -} - -std::shared_ptr -srsran::create_pdsch_processor_pool(std::shared_ptr pdsch_proc_factory, - unsigned max_nof_processors) -{ - return std::make_shared(std::move(pdsch_proc_factory), max_nof_processors); -} - std::shared_ptr srsran::create_prach_detector_factory_sw(std::shared_ptr dft_factory, std::shared_ptr prach_gen_factory, @@ -1148,85 +748,6 @@ class logging_pdcch_processor_decorator : public pdcch_processor std::unique_ptr processor; }; -class logging_pdsch_processor_decorator : public pdsch_processor, private pdsch_processor_notifier -{ -public: - logging_pdsch_processor_decorator(srslog::basic_logger& logger_, - bool enable_logging_broadcast_, - std::unique_ptr processor_) : - logger(logger_), enable_logging_broadcast(enable_logging_broadcast_), processor(std::move(processor_)) - { - srsran_assert(processor, "Invalid processor."); - } - - void process(resource_grid_mapper& mapper, - pdsch_processor_notifier& notifier_, - static_vector, MAX_NOF_TRANSPORT_BLOCKS> data_, - const pdu_t& pdu_) override - { - notifier = ¬ifier_; - data = data_.front(); - pdu = pdu_; - - start = std::chrono::steady_clock::now(); - processor->process(mapper, *this, data_, pdu); - } - -private: - void on_finish_processing() override - { - // Finish time measurement. - auto end = std::chrono::steady_clock::now(); - - // Only print if it is allowed. - if (enable_logging_broadcast || !is_broadcast_rnti(pdu.rnti)) { - // Get elapsed time. - std::chrono::nanoseconds time_ns = std::chrono::duration_cast(end - start); - - if (logger.debug.enabled()) { - // Detailed log information, including a list of all PDU fields. - logger.debug(pdu.slot.sfn(), - pdu.slot.slot_index(), - data.data(), - data.size(), - "PDSCH: {:s} tbs={} {}\n {:n}", - pdu, - data.size(), - time_ns, - pdu); - } else { - // Single line log entry. - logger.info(pdu.slot.sfn(), - pdu.slot.slot_index(), - data.data(), - data.size(), - "PDSCH: {:s} tbs={} {}", - pdu, - data.size(), - time_ns); - } - } - - // Verify the notifier is valid. - srsran_assert(notifier != nullptr, "Detected PDSCH processor notified twice."); - - // Set notifier to invalid pointer before notification. - pdsch_processor_notifier* notifier_ = notifier; - notifier = nullptr; - - // Notify original callback. Processor will be available after returning. - notifier_->on_finish_processing(); - } - - srslog::basic_logger& logger; - bool enable_logging_broadcast; - std::unique_ptr processor; - pdsch_processor_notifier* notifier; - span data; - pdu_t pdu; - std::chrono::time_point start; -}; - class logging_prach_detector_decorator : public prach_detector { public: @@ -1380,12 +901,6 @@ std::unique_ptr pdcch_processor_factory::create(srslog::basic_l return std::make_unique(logger, enable_logging_broadcast, create()); } -std::unique_ptr pdsch_processor_factory::create(srslog::basic_logger& logger, - bool enable_logging_broadcast) -{ - return std::make_unique(logger, enable_logging_broadcast, create()); -} - std::unique_ptr prach_detector_factory::create(srslog::basic_logger& logger, bool log_all_opportunities) { return std::make_unique(logger, log_all_opportunities, create()); diff --git a/lib/phy/upper/channel_processors/pdsch/CMakeLists.txt b/lib/phy/upper/channel_processors/pdsch/CMakeLists.txt new file mode 100644 index 0000000000..5e18c74431 --- /dev/null +++ b/lib/phy/upper/channel_processors/pdsch/CMakeLists.txt @@ -0,0 +1,20 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +add_library(srsran_pdsch_processor STATIC + factories.cpp + pdsch_codeblock_processor.cpp + pdsch_encoder_hw_impl.cpp + pdsch_encoder_impl.cpp + pdsch_modulator_impl.cpp + pdsch_processor_concurrent_impl.cpp + pdsch_processor_impl.cpp + pdsch_processor_lite_impl.cpp + pdsch_processor_validator_impl.cpp) + +target_link_libraries(srsran_pdsch_processor srsran_upper_phy_support srsran_ran) diff --git a/lib/phy/upper/channel_processors/pdsch/factories.cpp b/lib/phy/upper/channel_processors/pdsch/factories.cpp new file mode 100644 index 0000000000..2e0457c842 --- /dev/null +++ b/lib/phy/upper/channel_processors/pdsch/factories.cpp @@ -0,0 +1,427 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" +#include "logging_pdsch_processor_decorator.h" +#include "pdsch_encoder_hw_impl.h" +#include "pdsch_encoder_impl.h" +#include "pdsch_modulator_impl.h" +#include "pdsch_processor_asynchronous_pool.h" +#include "pdsch_processor_concurrent_impl.h" +#include "pdsch_processor_impl.h" +#include "pdsch_processor_lite_impl.h" +#include "pdsch_processor_pool.h" +#include "pdsch_processor_validator_impl.h" +#include + +using namespace srsran; + +namespace { + +class pdsch_encoder_factory_sw : public pdsch_encoder_factory +{ +private: + std::shared_ptr encoder_factory; + std::shared_ptr rate_matcher_factory; + std::shared_ptr segmenter_factory; + +public: + explicit pdsch_encoder_factory_sw(pdsch_encoder_factory_sw_configuration& config) : + encoder_factory(std::move(config.encoder_factory)), + rate_matcher_factory(std::move(config.rate_matcher_factory)), + segmenter_factory(std::move(config.segmenter_factory)) + { + srsran_assert(encoder_factory, "Invalid LDPC encoder factory."); + srsran_assert(rate_matcher_factory, "Invalid LDPC RM factory."); + srsran_assert(segmenter_factory, "Invalid LDPC segmenter factory."); + } + + std::unique_ptr create() override + { + return std::make_unique( + segmenter_factory->create(), encoder_factory->create(), rate_matcher_factory->create()); + } +}; + +/// HW-accelerated PDSCH encoder factory. +class pdsch_encoder_factory_hw : public pdsch_encoder_factory +{ +private: + std::shared_ptr crc_factory; + std::shared_ptr segmenter_factory; + std::shared_ptr hw_encoder_factory; + +public: + explicit pdsch_encoder_factory_hw(const pdsch_encoder_factory_hw_configuration& config) : + crc_factory(std::move(config.crc_factory)), + segmenter_factory(std::move(config.segmenter_factory)), + hw_encoder_factory(std::move(config.hw_encoder_factory)) + { + srsran_assert(crc_factory, "Invalid CRC factory."); + srsran_assert(segmenter_factory, "Invalid LDPC segmenter factory."); + srsran_assert(hw_encoder_factory, "Invalid hardware accelerator factory."); + } + + std::unique_ptr create() override + { + pdsch_encoder_hw_impl::sch_crc crc = { + crc_factory->create(crc_generator_poly::CRC16), + crc_factory->create(crc_generator_poly::CRC24A), + crc_factory->create(crc_generator_poly::CRC24B), + }; + return std::make_unique(crc, segmenter_factory->create(), hw_encoder_factory->create()); + } +}; + +class pdsch_modulator_factory_sw : public pdsch_modulator_factory +{ +private: + std::shared_ptr modulator_factory; + std::shared_ptr prg_factory; + +public: + pdsch_modulator_factory_sw(std::shared_ptr modulator_factory_, + std::shared_ptr prg_factory_) : + modulator_factory(std::move(modulator_factory_)), prg_factory(std::move(prg_factory_)) + { + srsran_assert(modulator_factory, "Invalid modulator factory."); + srsran_assert(prg_factory, "Invalid PRG factory."); + } + + std::unique_ptr create() override + { + return std::make_unique(modulator_factory->create_modulation_mapper(), prg_factory->create()); + } +}; + +class pdsch_processor_factory_sw : public pdsch_processor_factory +{ +private: + std::shared_ptr encoder_factory; + std::shared_ptr modulator_factory; + std::shared_ptr dmrs_factory; + +public: + pdsch_processor_factory_sw(std::shared_ptr encoder_factory_, + std::shared_ptr modulator_factory_, + std::shared_ptr dmrs_factory_) : + encoder_factory(std::move(encoder_factory_)), + modulator_factory(std::move(modulator_factory_)), + dmrs_factory(std::move(dmrs_factory_)) + { + srsran_assert(encoder_factory, "Invalid encoder factory."); + srsran_assert(modulator_factory, "Invalid modulator factory."); + srsran_assert(dmrs_factory, "Invalid DM-RS factory."); + } + + std::unique_ptr create() override + { + return std::make_unique( + encoder_factory->create(), modulator_factory->create(), dmrs_factory->create()); + } + + std::unique_ptr create_validator() override + { + return std::make_unique(); + } +}; + +class pdsch_processor_concurrent_factory_sw : public pdsch_processor_factory +{ +public: + pdsch_processor_concurrent_factory_sw(std::shared_ptr crc_factory, + std::shared_ptr encoder_factory, + std::shared_ptr rate_matcher_factory, + std::shared_ptr prg_factory_, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory, + task_executor& executor_, + unsigned nof_concurrent_threads) : + prg_factory(std::move(prg_factory_)), executor(executor_) + { + srsran_assert(crc_factory, "Invalid CRC calculator factory."); + srsran_assert(encoder_factory, "Invalid encoder factory."); + srsran_assert(rate_matcher_factory, "Invalid rate matcher factory."); + srsran_assert(prg_factory, "Invalid PRG factory."); + srsran_assert(modulator_factory, "Invalid modulator factory."); + srsran_assert(dmrs_factory, "Invalid DM-RS factory."); + srsran_assert(nof_concurrent_threads > 1, "Number of concurrent threads must be greater than one."); + + // Create vector of codeblock processors. + std::vector> cb_processors; + for (unsigned i_encoder = 0; i_encoder != nof_concurrent_threads; ++i_encoder) { + cb_processors.emplace_back( + std::make_unique(crc_factory->create(crc_generator_poly::CRC24A), + crc_factory->create(crc_generator_poly::CRC24B), + crc_factory->create(crc_generator_poly::CRC16), + encoder_factory->create(), + rate_matcher_factory->create(), + prg_factory->create(), + modulator_factory->create_modulation_mapper())); + } + + // Create pool of codeblock processors. It is common for all PDSCH processors. + cb_processor_pool = + std::make_shared(std::move(cb_processors)); + + // Create vector of PDSCH DM-RS generators. + std::vector> dmrs_generators; + for (unsigned i_encoder = 0; i_encoder != nof_concurrent_threads; ++i_encoder) { + dmrs_generators.emplace_back(dmrs_factory->create()); + } + + // Create pool of PDSCH DM-RS generators. It is common for all PDSCH processors. + dmrs_generator_pool = + std::make_shared(std::move(dmrs_generators)); + } + + std::unique_ptr create() override + { + return std::make_unique( + cb_processor_pool, prg_factory->create(), dmrs_generator_pool, ptrs_generator_pool, executor); + } + + std::unique_ptr create_validator() override + { + return std::make_unique(); + } + +private: + std::shared_ptr prg_factory; + task_executor& executor; + std::shared_ptr cb_processor_pool; + std::shared_ptr dmrs_generator_pool; + std::shared_ptr ptrs_generator_pool; +}; + +class pdsch_processor_lite_factory_sw : public pdsch_processor_factory +{ +private: + std::shared_ptr segmenter_factory; + std::shared_ptr encoder_factory; + std::shared_ptr rate_matcher_factory; + std::shared_ptr scrambler_factory; + std::shared_ptr modulator_factory; + std::shared_ptr dmrs_factory; + +public: + pdsch_processor_lite_factory_sw(std::shared_ptr segmenter_factory_, + std::shared_ptr encoder_factory_, + std::shared_ptr rate_matcher_factory_, + std::shared_ptr scrambler_factory_, + std::shared_ptr modulator_factory_, + std::shared_ptr dmrs_factory_) : + segmenter_factory(std::move(segmenter_factory_)), + encoder_factory(std::move(encoder_factory_)), + rate_matcher_factory(std::move(rate_matcher_factory_)), + scrambler_factory(std::move(scrambler_factory_)), + modulator_factory(std::move(modulator_factory_)), + dmrs_factory(std::move(dmrs_factory_)) + { + srsran_assert(segmenter_factory, "Invalid segmenter factory."); + srsran_assert(encoder_factory, "Invalid encoder factory."); + srsran_assert(rate_matcher_factory, "Invalid rate matcher factory."); + srsran_assert(scrambler_factory, "Invalid scrambler factory."); + srsran_assert(modulator_factory, "Invalid modulator factory."); + srsran_assert(dmrs_factory, "Invalid DM-RS factory."); + } + + std::unique_ptr create() override + { + return std::make_unique(segmenter_factory->create(), + encoder_factory->create(), + rate_matcher_factory->create(), + scrambler_factory->create(), + modulator_factory->create_modulation_mapper(), + dmrs_factory->create()); + } + + std::unique_ptr create_validator() override + { + return std::make_unique(); + } +}; + +class pdsch_processor_asynchronous_pool_factory : public pdsch_processor_factory +{ +public: + pdsch_processor_asynchronous_pool_factory(std::shared_ptr factory_, + unsigned max_nof_processors_) : + factory(std::move(factory_)), max_nof_processors(max_nof_processors_) + { + srsran_assert(factory, "Invalid PDSCH processor factory."); + srsran_assert(max_nof_processors >= 1, + "The number of processors (i.e., {}) must be greater than or equal to one.", + max_nof_processors); + } + + std::unique_ptr create() override + { + // Create processors. + std::vector> processors(max_nof_processors); + for (std::unique_ptr& processor : processors) { + processor = factory->create(); + } + + return std::make_unique(processors, false); + } + + std::unique_ptr create(srslog::basic_logger& logger, bool enable_logging_broadcast) override + { + // Create processors with logging. + std::vector> processors(max_nof_processors); + for (std::unique_ptr& processor : processors) { + processor = factory->create(logger, enable_logging_broadcast); + } + + return std::make_unique(processors, false); + } + + std::unique_ptr create_validator() override { return factory->create_validator(); } + +private: + std::shared_ptr factory; + unsigned max_nof_processors; +}; + +class pdsch_processor_pool_factory : public pdsch_processor_factory +{ +public: + pdsch_processor_pool_factory(std::shared_ptr factory_, unsigned max_nof_processors_) : + factory(std::move(factory_)), max_nof_processors(max_nof_processors_) + { + srsran_assert(factory, "Invalid PDSCH processor factory."); + srsran_assert(max_nof_processors != 0, "The number of processors must not be zero."); + } + + std::unique_ptr create() override + { + // Creates the processors without logging. + if (!processors) { + // Create PDSCH processsor instances. + std::vector> instances(max_nof_processors); + std::generate(instances.begin(), instances.end(), [this]() { return factory->create(); }); + + // Create pool. + processors = std::make_shared(std::move(instances)); + } + + return std::make_unique(processors); + } + + std::unique_ptr create(srslog::basic_logger& logger, bool enable_logging_broadcast) override + { + // Creates the processors with logging. + if (!processors) { + // Create PDSCH processor instances. + std::vector> instances(max_nof_processors); + std::generate(instances.begin(), instances.end(), [this, &logger, &enable_logging_broadcast]() { + return factory->create(logger, enable_logging_broadcast); + }); + + // Create pool. + processors = std::make_shared(std::move(instances)); + } + + return std::make_unique(processors); + } + + std::unique_ptr create_validator() override { return factory->create_validator(); } + +private: + std::shared_ptr factory; + std::shared_ptr processors; + unsigned max_nof_processors; +}; +} // namespace + +std::shared_ptr +srsran::create_pdsch_encoder_factory_sw(pdsch_encoder_factory_sw_configuration& config) +{ + return std::make_shared(config); +} + +std::shared_ptr +srsran::create_pdsch_encoder_factory_hw(const pdsch_encoder_factory_hw_configuration& config) +{ + return std::make_shared(config); +} + +std::shared_ptr +srsran::create_pdsch_modulator_factory_sw(std::shared_ptr modulator_factory, + std::shared_ptr prg_factory) +{ + return std::make_shared(std::move(modulator_factory), std::move(prg_factory)); +} + +std::shared_ptr +srsran::create_pdsch_processor_factory_sw(std::shared_ptr encoder_factory, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory) +{ + return std::make_shared( + std::move(encoder_factory), std::move(modulator_factory), std::move(dmrs_factory)); +} + +std::shared_ptr +srsran::create_pdsch_concurrent_processor_factory_sw(std::shared_ptr crc_factory, + std::shared_ptr ldpc_enc_factory, + std::shared_ptr ldpc_rm_factory, + std::shared_ptr prg_factory, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory, + task_executor& executor, + unsigned nof_concurrent_threads) +{ + return std::make_shared(std::move(crc_factory), + std::move(ldpc_enc_factory), + std::move(ldpc_rm_factory), + std::move(prg_factory), + std::move(modulator_factory), + std::move(dmrs_factory), + executor, + nof_concurrent_threads); +} + +std::shared_ptr +srsran::create_pdsch_lite_processor_factory_sw(std::shared_ptr segmenter_factory, + std::shared_ptr encoder_factory, + std::shared_ptr rate_matcher_factory, + std::shared_ptr scrambler_factory, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory) +{ + return std::make_shared(std::move(segmenter_factory), + std::move(encoder_factory), + std::move(rate_matcher_factory), + std::move(scrambler_factory), + std::move(modulator_factory), + std::move(dmrs_factory)); +} + +std::shared_ptr +srsran::create_pdsch_processor_asynchronous_pool(std::shared_ptr pdsch_proc_factory, + unsigned max_nof_processors) +{ + return std::make_shared(std::move(pdsch_proc_factory), max_nof_processors); +} + +std::shared_ptr +srsran::create_pdsch_processor_pool(std::shared_ptr pdsch_proc_factory, + unsigned max_nof_processors) +{ + return std::make_shared(std::move(pdsch_proc_factory), max_nof_processors); +} + +std::unique_ptr pdsch_processor_factory::create(srslog::basic_logger& logger, + bool enable_logging_broadcast) +{ + return std::make_unique(logger, enable_logging_broadcast, create()); +} \ No newline at end of file diff --git a/lib/phy/upper/channel_processors/pdsch/logging_pdsch_processor_decorator.h b/lib/phy/upper/channel_processors/pdsch/logging_pdsch_processor_decorator.h new file mode 100644 index 0000000000..6c87a1b76b --- /dev/null +++ b/lib/phy/upper/channel_processors/pdsch/logging_pdsch_processor_decorator.h @@ -0,0 +1,102 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/phy/support/support_formatters.h" +#include "srsran/phy/upper/channel_processors/pdsch/formatters.h" + +namespace srsran { + +inline bool is_broadcast_rnti(uint16_t rnti) +{ + return ((rnti < to_value(rnti_t::MIN_CRNTI)) || (rnti > to_value(rnti_t::MAX_CRNTI))); +} + +class logging_pdsch_processor_decorator : public pdsch_processor, private pdsch_processor_notifier +{ +public: + logging_pdsch_processor_decorator(srslog::basic_logger& logger_, + bool enable_logging_broadcast_, + std::unique_ptr processor_) : + logger(logger_), enable_logging_broadcast(enable_logging_broadcast_), processor(std::move(processor_)) + { + srsran_assert(processor, "Invalid processor."); + } + + void process(resource_grid_mapper& mapper, + pdsch_processor_notifier& notifier_, + static_vector, MAX_NOF_TRANSPORT_BLOCKS> data_, + const pdu_t& pdu_) override + { + notifier = ¬ifier_; + data = data_.front(); + pdu = pdu_; + + start = std::chrono::steady_clock::now(); + processor->process(mapper, *this, data_, pdu); + } + +private: + void on_finish_processing() override + { + // Finish time measurement. + auto end = std::chrono::steady_clock::now(); + + // Only print if it is allowed. + if (enable_logging_broadcast || !is_broadcast_rnti(pdu.rnti)) { + // Get elapsed time. + std::chrono::nanoseconds time_ns = std::chrono::duration_cast(end - start); + + if (logger.debug.enabled()) { + // Detailed log information, including a list of all PDU fields. + logger.debug(pdu.slot.sfn(), + pdu.slot.slot_index(), + data.data(), + data.size(), + "PDSCH: {:s} tbs={} {}\n {:n}", + pdu, + data.size(), + time_ns, + pdu); + } else { + // Single line log entry. + logger.info(pdu.slot.sfn(), + pdu.slot.slot_index(), + data.data(), + data.size(), + "PDSCH: {:s} tbs={} {}", + pdu, + data.size(), + time_ns); + } + } + + // Verify the notifier is valid. + srsran_assert(notifier != nullptr, "Detected PDSCH processor notified twice."); + + // Set notifier to invalid pointer before notification. + pdsch_processor_notifier* notifier_ = notifier; + notifier = nullptr; + + // Notify original callback. Processor will be available after returning. + notifier_->on_finish_processing(); + } + + srslog::basic_logger& logger; + bool enable_logging_broadcast; + std::unique_ptr processor; + pdsch_processor_notifier* notifier; + span data; + pdu_t pdu; + std::chrono::time_point start; +}; + +} // namespace srsran \ No newline at end of file diff --git a/lib/phy/upper/channel_processors/pdsch_codeblock_processor.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_codeblock_processor.cpp similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_codeblock_processor.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_codeblock_processor.cpp diff --git a/lib/phy/upper/channel_processors/pdsch_codeblock_processor.h b/lib/phy/upper/channel_processors/pdsch/pdsch_codeblock_processor.h similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_codeblock_processor.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_codeblock_processor.h diff --git a/lib/phy/upper/channel_processors/pdsch_encoder_hw_impl.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_encoder_hw_impl.cpp similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_encoder_hw_impl.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_encoder_hw_impl.cpp diff --git a/lib/phy/upper/channel_processors/pdsch_encoder_hw_impl.h b/lib/phy/upper/channel_processors/pdsch/pdsch_encoder_hw_impl.h similarity index 98% rename from lib/phy/upper/channel_processors/pdsch_encoder_hw_impl.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_encoder_hw_impl.h index 81ffc29516..73c666fda6 100644 --- a/lib/phy/upper/channel_processors/pdsch_encoder_hw_impl.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_encoder_hw_impl.h @@ -17,7 +17,7 @@ #include "srsran/hal/phy/upper/channel_processors/hw_accelerator_pdsch_enc.h" #include "srsran/phy/upper/channel_coding/crc_calculator.h" #include "srsran/phy/upper/channel_coding/ldpc/ldpc_segmenter_tx.h" -#include "srsran/phy/upper/channel_processors/pdsch_encoder.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h" #include "srsran/ran/pdsch/pdsch_constants.h" namespace srsran { diff --git a/lib/phy/upper/channel_processors/pdsch_encoder_impl.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_encoder_impl.cpp similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_encoder_impl.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_encoder_impl.cpp diff --git a/lib/phy/upper/channel_processors/pdsch_encoder_impl.h b/lib/phy/upper/channel_processors/pdsch/pdsch_encoder_impl.h similarity index 97% rename from lib/phy/upper/channel_processors/pdsch_encoder_impl.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_encoder_impl.h index 45b49e2578..ecd622368f 100644 --- a/lib/phy/upper/channel_processors/pdsch_encoder_impl.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_encoder_impl.h @@ -16,7 +16,7 @@ #include "srsran/phy/upper/channel_coding/ldpc/ldpc_encoder.h" #include "srsran/phy/upper/channel_coding/ldpc/ldpc_rate_matcher.h" #include "srsran/phy/upper/channel_coding/ldpc/ldpc_segmenter_tx.h" -#include "srsran/phy/upper/channel_processors/pdsch_encoder.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h" #include "srsran/phy/upper/codeblock_metadata.h" #include "srsran/ran/pdsch/pdsch_constants.h" diff --git a/lib/phy/upper/channel_processors/pdsch_modulator_impl.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_modulator_impl.cpp similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_modulator_impl.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_modulator_impl.cpp diff --git a/lib/phy/upper/channel_processors/pdsch_modulator_impl.h b/lib/phy/upper/channel_processors/pdsch/pdsch_modulator_impl.h similarity index 97% rename from lib/phy/upper/channel_processors/pdsch_modulator_impl.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_modulator_impl.h index a3b05f0d01..1cc195c2fd 100644 --- a/lib/phy/upper/channel_processors/pdsch_modulator_impl.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_modulator_impl.h @@ -12,7 +12,7 @@ #include "srsran/phy/support/re_buffer.h" #include "srsran/phy/support/resource_grid_mapper.h" -#include "srsran/phy/upper/channel_processors/pdsch_modulator.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_modulator.h" #include "srsran/phy/upper/sequence_generators/pseudo_random_generator.h" #include "srsran/ran/pdsch/pdsch_constants.h" diff --git a/lib/phy/upper/channel_processors/pdsch_processor_asynchronous_pool.h b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_asynchronous_pool.h similarity index 94% rename from lib/phy/upper/channel_processors/pdsch_processor_asynchronous_pool.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_asynchronous_pool.h index ac6caf2f7f..2c590257f6 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_asynchronous_pool.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_asynchronous_pool.h @@ -11,9 +11,14 @@ #pragma once #include "srsran/adt/concurrent_queue.h" -#include "srsran/phy/upper/channel_processors/channel_processor_formatters.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/adt/mpmc_queue.h" +#include "srsran/adt/span.h" +#include "srsran/phy/upper/channel_processors/pdsch/formatters.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/srslog/logger.h" +#include "srsran/srslog/srslog.h" +#include +#include namespace srsran { diff --git a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_concurrent_impl.cpp similarity index 76% rename from lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_concurrent_impl.cpp index b90718c2b3..4d60c81248 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.cpp +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_concurrent_impl.cpp @@ -12,6 +12,7 @@ #include "pdsch_processor_validator_impl.h" #include "srsran/instrumentation/traces/du_traces.h" #include "srsran/phy/support/resource_grid_mapper.h" +#include "srsran/ran/ptrs/ptrs_pattern.h" #include "srsran/support/event_tracing.h" using namespace srsran; @@ -30,6 +31,23 @@ void pdsch_processor_concurrent_impl::process(resource_grid_mapper& // Set the number of asynchronous tasks. It counts as CB processing and DM-RS generation. async_task_counter = 2; + // Add PT-RS to the asynchronous tasks. + if (config.ptrs) { + ++async_task_counter; + + // Process PT-RS concurrently. + auto ptrs_task = [this]() { process_ptrs(); }; + + bool success = false; + if (cb_processor_pool->capacity() > 1) { + success = executor.execute(ptrs_task); + } + + if (!success) { + ptrs_task(); + } + } + // Process DM-RS concurrently. auto dmrs_task = [this]() { process_dmrs(); }; if (!executor.execute(dmrs_task)) { @@ -212,9 +230,42 @@ unsigned pdsch_processor_concurrent_impl::compute_nof_data_re(const pdu_t& confi // Calculate the number of RE used by DM-RS. It assumes it does not overlap with reserved elements. unsigned nof_grid_dmrs = nof_prb * dmrs_pattern.re_mask.count() * dmrs_pattern.symbols.count(); + // Generate reserved pattern. + re_pattern_list reserved = config.reserved; + + // If the pattern contains PT-RS, append the reserved elements to the list. + if (config.ptrs) { + // Extract specific PT-RS configuration. + const ptrs_configuration& ptrs_config = config.ptrs.value(); + + // Create PT-RS pattern configuration. + ptrs_pattern_configuration ptrs_pattern_config = { + .rnti = to_rnti(config.rnti), + .dmrs_type = (config.dmrs == dmrs_type::TYPE1) ? dmrs_config_type::type1 : dmrs_config_type::type2, + .dmrs_symbol_mask = config.dmrs_symbol_mask, + .rb_mask = prb_mask, + .time_allocation = {config.start_symbol_index, config.start_symbol_index + config.nof_symbols}, + .freq_density = ptrs_config.freq_density, + .time_density = ptrs_config.time_density, + .re_offset = ptrs_config.re_offset, + .nof_ports = 1}; + + // Calculate PT-RS pattern and convert it to an RE pattern. + ptrs_pattern ptrs_reserved_pattern = get_ptrs_pattern(ptrs_pattern_config); + + re_pattern ptrs_reserved_re_pattern; + for (unsigned i_prb = ptrs_reserved_pattern.rb_begin; i_prb < ptrs_reserved_pattern.rb_end; + i_prb += ptrs_reserved_pattern.rb_stride) { + ptrs_reserved_re_pattern.prb_mask.set(i_prb); + } + ptrs_reserved_re_pattern.symbols = ptrs_reserved_pattern.symbol_mask; + ptrs_reserved_re_pattern.re_mask.set(ptrs_reserved_pattern.re_offset.front()); + + reserved.merge(ptrs_reserved_re_pattern); + } + // Calculate the number of reserved resource elements. - unsigned nof_reserved_re = - config.reserved.get_inclusion_count(config.start_symbol_index, config.nof_symbols, prb_mask); + unsigned nof_reserved_re = reserved.get_inclusion_count(config.start_symbol_index, config.nof_symbols, prb_mask); // Subtract the number of reserved RE from the number of allocated RE. srsran_assert(nof_grid_re > nof_reserved_re, @@ -338,3 +389,51 @@ void pdsch_processor_concurrent_impl::process_dmrs() notifier->on_finish_processing(); } } + +void pdsch_processor_concurrent_impl::process_ptrs() +{ + trace_point process_ptrs_tp = l1_tracer.now(); + + // Extract PT-RS configuration parameters. + const ptrs_configuration& ptrs = config.ptrs.value(); + + bounded_bitset rb_mask_bitset = config.freq_alloc.get_prb_mask(config.bwp_start_rb, config.bwp_size_rb); + + // Select the DM-RS reference point. + unsigned ptrs_reference_point_k_rb = 0; + if (config.ref_point == pdu_t::PRB0) { + ptrs_reference_point_k_rb = config.bwp_start_rb; + } + + // Calculate the PT-RS sequence amplitude following TS38.214 Section 4.1. + float amplitude = convert_dB_to_amplitude(ptrs.ratio_ptrs_to_pdsch_data_dB - config.ratio_pdsch_data_to_sss_dB); + + // Prepare PT-RS configuration. + ptrs_pdsch_generator::configuration ptrs_config; + ptrs_config.slot = config.slot; + ptrs_config.rnti = to_rnti(config.rnti); + ptrs_config.dmrs_config_type = config.dmrs; + ptrs_config.reference_point_k_rb = ptrs_reference_point_k_rb; + ptrs_config.scrambling_id = config.scrambling_id; + ptrs_config.n_scid = config.n_scid; + ptrs_config.amplitude = amplitude; + ptrs_config.dmrs_symbols_mask = config.dmrs_symbol_mask; + ptrs_config.rb_mask = rb_mask_bitset; + ptrs_config.time_allocation = {config.start_symbol_index, config.start_symbol_index + config.nof_symbols}; + ptrs_config.freq_density = ptrs.freq_density; + ptrs_config.time_density = ptrs.time_density; + ptrs_config.re_offset = ptrs.re_offset; + ptrs_config.reserved = config.reserved; + ptrs_config.precoding = config.precoding; + + // Put PT-RS. + ptrs_generator_pool->get().generate(*mapper, ptrs_config); + + l1_tracer << trace_event("process_ptrs", process_ptrs_tp); + + // Decrement asynchronous task counter. + if (async_task_counter.fetch_sub(1) == 1) { + // Notify end of the processing. + notifier->on_finish_processing(); + } +} diff --git a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.h b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_concurrent_impl.h similarity index 90% rename from lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_concurrent_impl.h index 4ededdca58..bffb26ea17 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_concurrent_impl.h @@ -11,9 +11,10 @@ #include "pdsch_codeblock_processor.h" #include "srsran/phy/support/resource_grid_mapper.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/phy/upper/sequence_generators/pseudo_random_generator.h" #include "srsran/phy/upper/signal_processors/dmrs_pdsch_processor.h" +#include "srsran/phy/upper/signal_processors/ptrs/ptrs_pdsch_generator.h" #include "srsran/support/executors/task_executor.h" #include "srsran/support/memory_pool/concurrent_thread_local_object_pool.h" @@ -29,6 +30,8 @@ class pdsch_processor_concurrent_impl : public pdsch_processor using codeblock_processor_pool = concurrent_thread_local_object_pool; /// PDSCH DM-RS generator pool type. using pdsch_dmrs_generator_pool = concurrent_thread_local_object_pool; + /// PDSCH PT-RS generator pool type. + using pdsch_ptrs_generator_pool = concurrent_thread_local_object_pool; /// \brief Creates a concurrent PDSCH processor with all the dependencies. /// \param[in] cb_processor_pool_ Codeblock processor pool. @@ -38,10 +41,12 @@ class pdsch_processor_concurrent_impl : public pdsch_processor pdsch_processor_concurrent_impl(std::shared_ptr cb_processor_pool_, std::unique_ptr scrambler_, std::shared_ptr dmrs_generator_pool_, + std::shared_ptr ptrs_generator_pool_, task_executor& executor_) : scrambler(std::move(scrambler_)), cb_processor_pool(std::move(cb_processor_pool_)), dmrs_generator_pool(std::move(dmrs_generator_pool_)), + ptrs_generator_pool(std::move(ptrs_generator_pool_)), executor(executor_) { srsran_assert(scrambler, "Invalid scrambler pointer."); @@ -76,12 +81,17 @@ class pdsch_processor_concurrent_impl : public pdsch_processor /// Processes PDSCH DM-RS. void process_dmrs(); + /// Processes PDSCH PT-RS. + void process_ptrs(); + /// Pseudo-random generator. std::unique_ptr scrambler; /// Pool of code block processors. std::shared_ptr cb_processor_pool; /// DM-RS processor. std::shared_ptr dmrs_generator_pool; + /// PT-RS processor. + std::shared_ptr ptrs_generator_pool; /// Asynchronous task executor. task_executor& executor; diff --git a/lib/phy/upper/channel_processors/pdsch_processor_impl.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_impl.cpp similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_processor_impl.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_impl.cpp diff --git a/lib/phy/upper/channel_processors/pdsch_processor_impl.h b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_impl.h similarity index 94% rename from lib/phy/upper/channel_processors/pdsch_processor_impl.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_impl.h index 2b5e5351dd..f786c24d53 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_impl.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_impl.h @@ -9,9 +9,9 @@ */ #pragma once -#include "srsran/phy/upper/channel_processors/pdsch_encoder.h" -#include "srsran/phy/upper/channel_processors/pdsch_modulator.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_modulator.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/phy/upper/signal_processors/dmrs_pdsch_processor.h" #include "srsran/ran/pdsch/pdsch_constants.h" diff --git a/lib/phy/upper/channel_processors/pdsch_processor_lite_impl.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_lite_impl.cpp similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_processor_lite_impl.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_lite_impl.cpp diff --git a/lib/phy/upper/channel_processors/pdsch_processor_lite_impl.h b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_lite_impl.h similarity index 97% rename from lib/phy/upper/channel_processors/pdsch_processor_lite_impl.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_lite_impl.h index d75fa5e66f..1b7bfa220a 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_lite_impl.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_lite_impl.h @@ -15,8 +15,8 @@ #include "srsran/phy/upper/channel_coding/ldpc/ldpc_rate_matcher.h" #include "srsran/phy/upper/channel_coding/ldpc/ldpc_segmenter_tx.h" #include "srsran/phy/upper/channel_modulation/modulation_mapper.h" -#include "srsran/phy/upper/channel_processors/pdsch_encoder.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/phy/upper/sequence_generators/pseudo_random_generator.h" #include "srsran/phy/upper/signal_processors/dmrs_pdsch_processor.h" #include "srsran/ran/pdsch/pdsch_constants.h" diff --git a/lib/phy/upper/channel_processors/pdsch_processor_pool.h b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_pool.h similarity index 96% rename from lib/phy/upper/channel_processors/pdsch_processor_pool.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_pool.h index 4e0107ad5b..f80612fd29 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_pool.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_pool.h @@ -12,7 +12,7 @@ #include "srsran/adt/concurrent_queue.h" #include "srsran/phy/upper/channel_processors/channel_processor_formatters.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/srslog/logger.h" namespace srsran { diff --git a/lib/phy/upper/channel_processors/pdsch_processor_validator_impl.cpp b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_validator_impl.cpp similarity index 100% rename from lib/phy/upper/channel_processors/pdsch_processor_validator_impl.cpp rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_validator_impl.cpp diff --git a/lib/phy/upper/channel_processors/pdsch_processor_validator_impl.h b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_validator_impl.h similarity index 90% rename from lib/phy/upper/channel_processors/pdsch_processor_validator_impl.h rename to lib/phy/upper/channel_processors/pdsch/pdsch_processor_validator_impl.h index 939be70315..3da787ed66 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_validator_impl.h +++ b/lib/phy/upper/channel_processors/pdsch/pdsch_processor_validator_impl.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" namespace srsran { diff --git a/lib/phy/upper/downlink_processor_single_executor_impl.cpp b/lib/phy/upper/downlink_processor_single_executor_impl.cpp index b4e85daa03..79179fa644 100644 --- a/lib/phy/upper/downlink_processor_single_executor_impl.cpp +++ b/lib/phy/upper/downlink_processor_single_executor_impl.cpp @@ -15,6 +15,7 @@ #include "srsran/phy/upper/signal_processors/signal_processor_formatters.h" #include "srsran/phy/upper/upper_phy_rg_gateway.h" #include "srsran/support/executors/task_executor.h" +#include "srsran/support/srsran_assert.h" using namespace srsran; diff --git a/lib/phy/upper/downlink_processor_single_executor_state.h b/lib/phy/upper/downlink_processor_single_executor_state.h index 30c303720c..d61aedaf55 100644 --- a/lib/phy/upper/downlink_processor_single_executor_state.h +++ b/lib/phy/upper/downlink_processor_single_executor_state.h @@ -10,6 +10,7 @@ #pragma once +#include "srsran/phy/upper/channel_processors/pdsch/formatters.h" #include "srsran/support/srsran_assert.h" namespace srsran { diff --git a/lib/phy/upper/upper_phy_factories.cpp b/lib/phy/upper/upper_phy_factories.cpp index c602570604..31957403f4 100644 --- a/lib/phy/upper/upper_phy_factories.cpp +++ b/lib/phy/upper/upper_phy_factories.cpp @@ -20,6 +20,7 @@ #include "srsran/phy/support/support_factories.h" #include "srsran/phy/upper/channel_estimation.h" #include "srsran/phy/upper/channel_processors/channel_processor_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" #include "srsran/phy/upper/channel_processors/pusch/factories.h" #include "srsran/phy/upper/signal_processors/srs/srs_estimator_factory.h" #include "srsran/phy/upper/unique_rx_buffer.h" diff --git a/tests/benchmarks/phy/upper/channel_processors/pdsch_encoder_hwacc_benchmark.cpp b/tests/benchmarks/phy/upper/channel_processors/pdsch_encoder_hwacc_benchmark.cpp index 09ecc0864a..78ec2be084 100644 --- a/tests/benchmarks/phy/upper/channel_processors/pdsch_encoder_hwacc_benchmark.cpp +++ b/tests/benchmarks/phy/upper/channel_processors/pdsch_encoder_hwacc_benchmark.cpp @@ -14,7 +14,8 @@ /// The benchmark compares the latency of a hardware-accelerated PDSCH encoder implementation to that of the generic /// one. -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_encoder.h" #include "srsran/ran/pdsch/pdsch_constants.h" #include "srsran/ran/sch/tbs_calculator.h" #include "srsran/support/srsran_test.h" diff --git a/tests/benchmarks/phy/upper/channel_processors/pdsch_processor_benchmark.cpp b/tests/benchmarks/phy/upper/channel_processors/pdsch_processor_benchmark.cpp index 89f5da3c16..95e69972e5 100644 --- a/tests/benchmarks/phy/upper/channel_processors/pdsch_processor_benchmark.cpp +++ b/tests/benchmarks/phy/upper/channel_processors/pdsch_processor_benchmark.cpp @@ -8,9 +8,9 @@ * */ -#include "../../../../unittests/phy/upper/channel_processors/pdsch_processor_test_doubles.h" +#include "../../../../unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_doubles.h" #include "srsran/phy/support/support_factories.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" #include "srsran/ran/precoding/precoding_codebooks.h" #include "srsran/ran/sch/tbs_calculator.h" #include "srsran/support/benchmark_utils.h" @@ -438,29 +438,31 @@ static std::vector generate_test_cases(const test_profile& profi unsigned tbs = tbs_calculator_calculate(tbs_config); // Build the PDSCH PDU configuration. - pdsch_processor::pdu_t config = {std::nullopt, - slot_point(to_numerology_value(profile.scs), 0), - 1, - nof_prb, - 0, - profile.cp, - {pdsch_processor::codeword_description{mcs.modulation, i_rv}}, - 0, - pdsch_processor::pdu_t::CRB0, - dmrs_symbol_mask, - dmrs_type::options::TYPE1, - 0, - false, - nof_cdm_groups_without_data, - rb_allocation::make_type1(config.bwp_start_rb, nof_prb), - profile.start_symbol, - profile.nof_symbols, - get_ldpc_base_graph(mcs.get_normalised_target_code_rate(), units::bits(tbs)), - units::bits(ldpc::MAX_CODEBLOCK_SIZE).truncate_to_bytes(), - {}, - 0.0, - 0.0, - precoding_config}; + pdsch_processor::pdu_t config = { + .context = std::nullopt, + .slot = slot_point(to_numerology_value(profile.scs), 0), + .rnti = 1, + .bwp_size_rb = nof_prb, + .bwp_start_rb = 0, + .cp = profile.cp, + .codewords = {pdsch_processor::codeword_description{mcs.modulation, i_rv}}, + .n_id = 0, + .ref_point = pdsch_processor::pdu_t::CRB0, + .dmrs_symbol_mask = dmrs_symbol_mask, + .dmrs = dmrs_type::options::TYPE1, + .scrambling_id = 0, + .n_scid = false, + .nof_cdm_groups_without_data = nof_cdm_groups_without_data, + .freq_alloc = rb_allocation::make_type1(config.bwp_start_rb, nof_prb), + .start_symbol_index = profile.start_symbol, + .nof_symbols = profile.nof_symbols, + .ldpc_base_graph = get_ldpc_base_graph(mcs.get_normalised_target_code_rate(), units::bits(tbs)), + .tbs_lbrm = units::bits(ldpc::MAX_CODEBLOCK_SIZE).truncate_to_bytes(), + .reserved = {}, + .ptrs = std::nullopt, + .ratio_pdsch_dmrs_to_sss_dB = 0.0, + .ratio_pdsch_data_to_sss_dB = 0.0, + .precoding = precoding_config}; test_case_set.emplace_back(std::tuple(config, tbs)); } } diff --git a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp index 22239dd702..6351955134 100644 --- a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp +++ b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp @@ -20,6 +20,7 @@ #include "srsran/phy/upper/unique_rx_buffer.h" #include "srsran/ran/precoding/precoding_codebooks.h" #include "srsran/ran/pusch/pusch_mcs.h" +#include "srsran/ran/resource_allocation/rb_interval.h" #include "srsran/ran/sch/sch_dmrs_power.h" #include "srsran/ran/sch/sch_mcs.h" #include "srsran/ran/sch/tbs_calculator.h" diff --git a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_factories.h b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_factories.h index 1cb1705a74..3ae0bc1840 100644 --- a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_factories.h +++ b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test_factories.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" #include "srsran/phy/upper/channel_processors/pusch/factories.h" namespace srsran { diff --git a/tests/integrationtests/phy/upper/channel_processors/pxsch_chain_test.cpp b/tests/integrationtests/phy/upper/channel_processors/pxsch_chain_test.cpp index 23bba056b2..5869525293 100644 --- a/tests/integrationtests/phy/upper/channel_processors/pxsch_chain_test.cpp +++ b/tests/integrationtests/phy/upper/channel_processors/pxsch_chain_test.cpp @@ -10,7 +10,7 @@ #include "srsran/phy/constants.h" #include "srsran/phy/upper/channel_coding/channel_coding_factories.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" #include "srsran/phy/upper/channel_processors/pusch/factories.h" #include "srsran/phy/upper/channel_processors/pusch/pusch_decoder_buffer.h" #include "srsran/phy/upper/channel_processors/pusch/pusch_decoder_notifier.h" @@ -20,6 +20,7 @@ #include "srsran/ran/pdsch/dlsch_info.h" #include "srsran/ran/pdsch/pdsch_mcs.h" #include "srsran/ran/pusch/pusch_constants.h" +#include "srsran/ran/resource_allocation/rb_interval.h" #include "srsran/ran/sch/sch_mcs.h" #include "srsran/ran/sch/tbs_calculator.h" #include "srsran/srsvec/bit.h" diff --git a/tests/unittests/phy/upper/channel_processors/CMakeLists.txt b/tests/unittests/phy/upper/channel_processors/CMakeLists.txt index 526d0a2b56..cc4c222ae3 100644 --- a/tests/unittests/phy/upper/channel_processors/CMakeLists.txt +++ b/tests/unittests/phy/upper/channel_processors/CMakeLists.txt @@ -6,6 +6,7 @@ # the distribution. # +add_subdirectory(pdsch) add_subdirectory(pusch) add_subdirectory(uci) @@ -18,22 +19,6 @@ add_executable(pdcch_processor_unittest pdcch_processor_unittest.cpp) target_link_libraries(pdcch_processor_unittest srsran_channel_processors srslog) add_test(pdcch_processor_unittest pdcch_processor_unittest) -add_executable(pdsch_processor_unittest pdsch_processor_unittest.cpp) -target_link_libraries(pdsch_processor_unittest srsran_channel_processors srslog gtest gtest_main) -add_test(pdsch_processor_unittest pdsch_processor_unittest) - -add_executable(pdsch_processor_validator_test pdsch_processor_validator_test.cpp) -target_link_libraries(pdsch_processor_validator_test - srsran_channel_equalizer - srsran_channel_processors - srsran_phy_support - srslog - srsran_upper_phy_support - - gtest - gtest_main) -add_test(pdsch_processor_validator_test pdsch_processor_validator_test) - add_executable(pucch_processor_format1_unittest pucch_processor_format1_unittest.cpp) target_link_libraries(pucch_processor_format1_unittest srsran_channel_equalizer @@ -86,32 +71,6 @@ if (USE_PHY_TESTVECTORS) target_link_libraries(pdcch_processor_vectortest srsran_channel_processors srslog gtest gtest_main) add_test_vector(pdcch_processor_vectortest pdcch_processor_test_data.tar.gz "") - add_executable(pdsch_encoder_test pdsch_encoder_test.cpp) - set(PDSCH_ENCODER_LIBRARIES srsran_channel_processors srslog) - - if (ENABLE_PDSCH_HWACC) - set_source_files_properties(pdsch_encoder_test.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") - list(APPEND PDSCH_ENCODER_LIBRARIES hal_hwacc_pdsch) - endif (ENABLE_PDSCH_HWACC) - - target_link_libraries(pdsch_encoder_test ${PDSCH_ENCODER_LIBRARIES}) - add_test_vector(pdsch_encoder_test pdsch_encoder_test_data.tar.gz "") - - add_executable(pdsch_modulator_test pdsch_modulator_test.cpp) - target_link_libraries(pdsch_modulator_test srsran_channel_processors srslog) - add_test_vector(pdsch_modulator_test pdsch_modulator_test_data.tar.gz "") - - add_executable(pdsch_processor_vectortest pdsch_processor_vectortest.cpp) - set(PDSCH_PROCESSOR_LIBRARIES srsran_channel_processors srslog gtest gtest_main) - - if (ENABLE_PDSCH_HWACC) - set_source_files_properties(pdsch_processor_vectortest.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") - list(APPEND PDSCH_PROCESSOR_LIBRARIES hal_hwacc_pdsch) - endif (ENABLE_PDSCH_HWACC) - - target_link_libraries(pdsch_processor_vectortest ${PDSCH_PROCESSOR_LIBRARIES}) - add_test_vector(pdsch_processor_vectortest pdsch_processor_test_data.tar.gz "") - add_executable(prach_detector_vectortest prach_detector_vectortest.cpp) target_link_libraries(prach_detector_vectortest srsran_channel_processors srsran_generic_funcs srsran_phy_support srslog gtest gtest_main) add_test_vector(prach_detector_vectortest prach_detector_test_data.tar.gz "") diff --git a/tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt b/tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt new file mode 100644 index 0000000000..ef70e5439e --- /dev/null +++ b/tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt @@ -0,0 +1,54 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test_data) +set(TEST_DATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/test_data) + +set_directory_properties(PROPERTIES LABELS "phy") + +add_executable(pdsch_processor_unittest pdsch_processor_unittest.cpp) +target_link_libraries(pdsch_processor_unittest srsran_channel_processors srslog gtest gtest_main) +add_test(pdsch_processor_unittest pdsch_processor_unittest) + +add_executable(pdsch_processor_validator_test pdsch_processor_validator_test.cpp) +target_link_libraries(pdsch_processor_validator_test + srsran_channel_equalizer + srsran_channel_processors + srsran_phy_support + srslog + srsran_upper_phy_support + gtest + gtest_main) +add_test(pdsch_processor_validator_test pdsch_processor_validator_test) + +add_executable(pdsch_encoder_test pdsch_encoder_test.cpp) +set(PDSCH_ENCODER_LIBRARIES srsran_channel_processors srslog) + +if (ENABLE_PDSCH_HWACC) + set_source_files_properties(pdsch_encoder_test.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") + list(APPEND PDSCH_ENCODER_LIBRARIES hal_hwacc_pdsch) +endif (ENABLE_PDSCH_HWACC) + +target_link_libraries(pdsch_encoder_test ${PDSCH_ENCODER_LIBRARIES}) +add_test_vector(pdsch_encoder_test pdsch_encoder_test_data.tar.gz "") + +add_executable(pdsch_modulator_test pdsch_modulator_test.cpp) +target_link_libraries(pdsch_modulator_test srsran_channel_processors srslog) +add_test_vector(pdsch_modulator_test pdsch_modulator_test_data.tar.gz "") + +add_executable(pdsch_processor_vectortest pdsch_processor_vectortest.cpp) +set(PDSCH_PROCESSOR_LIBRARIES srsran_channel_processors srslog gtest gtest_main) + +if (ENABLE_PDSCH_HWACC) + set_source_files_properties(pdsch_processor_vectortest.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") + list(APPEND PDSCH_PROCESSOR_LIBRARIES hal_hwacc_pdsch) +endif (ENABLE_PDSCH_HWACC) + +target_link_libraries(pdsch_processor_vectortest ${PDSCH_PROCESSOR_LIBRARIES}) +add_test_vector(pdsch_processor_vectortest pdsch_processor_test_data.tar.gz "") + diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_encoder_test.cpp b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test.cpp similarity index 99% rename from tests/unittests/phy/upper/channel_processors/pdsch_encoder_test.cpp rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test.cpp index 8b8a8276fa..f81faf18aa 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_encoder_test.cpp +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test.cpp @@ -9,7 +9,7 @@ */ #include "pdsch_encoder_test_data.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" #include "srsran/support/srsran_test.h" #ifdef HWACC_PDSCH_ENABLED #include "srsran/hal/dpdk/bbdev/bbdev_acc.h" diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_data.h b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_data.h similarity index 99% rename from tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_data.h rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_data.h index 4743a33d03..235228fcc0 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_data.h +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_data.h @@ -10,7 +10,7 @@ #pragma once -// This file was generated using the following MATLAB class on 14-09-2023 (seed 0): +// This file was generated using the following MATLAB class on 29-08-2024 (seed 0): // + "srsPDSCHEncoderUnittest.m" #include "srsran/phy/upper/codeblock_metadata.h" diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_data.tar.gz b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_data.tar.gz similarity index 100% rename from tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_data.tar.gz rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_data.tar.gz diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_doubles.h b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_doubles.h similarity index 91% rename from tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_doubles.h rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_doubles.h index 03bb576a75..6278ece2f0 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_encoder_test_doubles.h +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_encoder_test_doubles.h @@ -1,8 +1,8 @@ #pragma once -#include "../../phy_test_utils.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" +#include "../../../phy_test_utils.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" #include "srsran/srsvec/copy.h" namespace srsran { diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_modulator_test.cpp b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test.cpp similarity index 89% rename from tests/unittests/phy/upper/channel_processors/pdsch_modulator_test.cpp rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test.cpp index 015ded6360..304d4d5c80 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_modulator_test.cpp +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test.cpp @@ -8,12 +8,10 @@ * */ -#include "../../support/resource_grid_mapper_test_doubles.h" +#include "../../../support/resource_grid_mapper_test_doubles.h" #include "pdsch_modulator_test_data.h" #include "srsran/phy/support/support_factories.h" -#include "srsran/phy/upper/channel_modulation/channel_modulation_factories.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" -#include "srsran/phy/upper/sequence_generators/sequence_generator_factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" #include "srsran/ran/pdsch/pdsch_constants.h" #include "srsran/srsvec/bit.h" diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_data.h b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_data.h similarity index 98% rename from tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_data.h rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_data.h index a4d3cead23..b517dd3456 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_data.h +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_data.h @@ -10,11 +10,11 @@ #pragma once -// This file was generated using the following MATLAB class on 14-09-2023 (seed 0): +// This file was generated using the following MATLAB class on 29-08-2024 (seed 0): // + "srsPDSCHModulatorUnittest.m" -#include "../../support/resource_grid_test_doubles.h" -#include "srsran/phy/upper/channel_processors/pdsch_modulator.h" +#include "../../../support/resource_grid_test_doubles.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_modulator.h" #include "srsran/ran/precoding/precoding_codebooks.h" #include "srsran/support/file_vector.h" diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_data.tar.gz b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_data.tar.gz similarity index 100% rename from tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_data.tar.gz rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_data.tar.gz diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_doubles.h b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_doubles.h similarity index 92% rename from tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_doubles.h rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_doubles.h index 72c0c6cab9..07f764be87 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_modulator_test_doubles.h +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_modulator_test_doubles.h @@ -1,7 +1,7 @@ #pragma once -#include "srsran/phy/upper/channel_processors/pdsch_modulator.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_modulator.h" #include namespace srsran { diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_processor_test_data.h b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_data.h similarity index 73% rename from tests/unittests/phy/upper/channel_processors/pdsch_processor_test_data.h rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_data.h index 861b3fb232..02c198a3ab 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_processor_test_data.h +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_data.h @@ -10,11 +10,11 @@ #pragma once -// This file was generated using the following MATLAB class on 17-05-2024 (seed 0): +// This file was generated using the following MATLAB class on 29-08-2024 (seed 0): // + "srsPDSCHProcessorUnittest.m" -#include "../../support/resource_grid_test_doubles.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "../../../support/resource_grid_test_doubles.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/ran/precoding/precoding_codebooks.h" #include "srsran/support/file_vector.h" @@ -37,30 +37,30 @@ struct test_case_t { static const std::vector pdsch_processor_test_data = { // clang-format off - {{26, 14, {std::nullopt, {1, 20}, 59859, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 647, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 6392, 0, 2, rb_allocation::make_type1(24, 1), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block0.dat"}, {"test_data/pdsch_processor_test_output_grid0.dat"}}, - {{26, 14, {std::nullopt, {0, 10}, 25542, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 247, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 26470, 0, 2, rb_allocation::make_type1(23, 2), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(1))}}, {"test_data/pdsch_processor_test_input_transport_block1.dat"}, {"test_data/pdsch_processor_test_output_grid1.dat"}}, - {{26, 14, {std::nullopt, {1, 4}, 42422, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 556, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 47254, 1, 2, rb_allocation::make_type1(2, 3), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block2.dat"}, {"test_data/pdsch_processor_test_output_grid2.dat"}}, - {{26, 14, {std::nullopt, {0, 8}, 15757, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 701, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 55001, 1, 2, rb_allocation::make_type1(14, 5), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block3.dat"}, {"test_data/pdsch_processor_test_output_grid3.dat"}}, - {{26, 14, {std::nullopt, {1, 4}, 2632, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 238, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 23665, 1, 2, rb_allocation::make_type1(18, 7), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block4.dat"}, {"test_data/pdsch_processor_test_output_grid4.dat"}}, - {{26, 14, {std::nullopt, {0, 4}, 52060, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 909, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 9339, 1, 2, rb_allocation::make_type1(0, 6), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block5.dat"}, {"test_data/pdsch_processor_test_output_grid5.dat"}}, - {{26, 14, {std::nullopt, {1, 3}, 22295, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 335, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 40302, 1, 2, rb_allocation::make_type1(16, 7), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block6.dat"}, {"test_data/pdsch_processor_test_output_grid6.dat"}}, - {{26, 14, {std::nullopt, {1, 17}, 28483, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 524, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 34372, 0, 2, rb_allocation::make_type1(7, 13), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block7.dat"}, {"test_data/pdsch_processor_test_output_grid7.dat"}}, - {{54, 14, {std::nullopt, {1, 14}, 24782, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 782, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 3629, 0, 2, rb_allocation::make_type1(29, 10), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block8.dat"}, {"test_data/pdsch_processor_test_output_grid8.dat"}}, - {{54, 14, {std::nullopt, {1, 4}, 6544, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 761, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 11194, 1, 2, rb_allocation::make_type1(27, 16), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block9.dat"}, {"test_data/pdsch_processor_test_output_grid9.dat"}}, - {{54, 14, {std::nullopt, {1, 7}, 15603, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 149, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 52284, 1, 2, rb_allocation::make_type1(45, 4), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block10.dat"}, {"test_data/pdsch_processor_test_output_grid10.dat"}}, - {{54, 14, {std::nullopt, {1, 2}, 11901, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 576, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 8145, 1, 2, rb_allocation::make_type1(27, 15), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block11.dat"}, {"test_data/pdsch_processor_test_output_grid11.dat"}}, - {{54, 14, {std::nullopt, {1, 12}, 52353, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 228, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 3202, 1, 2, rb_allocation::make_type1(21, 23), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block12.dat"}, {"test_data/pdsch_processor_test_output_grid12.dat"}}, - {{54, 14, {std::nullopt, {1, 0}, 13972, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 586, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 2299, 0, 2, rb_allocation::make_type1(38, 5), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block13.dat"}, {"test_data/pdsch_processor_test_output_grid13.dat"}}, - {{54, 14, {std::nullopt, {0, 7}, 45487, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 879, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 55393, 1, 2, rb_allocation::make_type1(17, 17), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block14.dat"}, {"test_data/pdsch_processor_test_output_grid14.dat"}}, - {{54, 14, {std::nullopt, {1, 19}, 4550, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 685, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 15237, 0, 2, rb_allocation::make_type1(51, 1), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block15.dat"}, {"test_data/pdsch_processor_test_output_grid15.dat"}}, - {{106, 14, {std::nullopt, {1, 6}, 22402, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 476, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 54514, 0, 2, rb_allocation::make_type1(66, 10), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block16.dat"}, {"test_data/pdsch_processor_test_output_grid16.dat"}}, - {{106, 14, {std::nullopt, {1, 2}, 26011, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 740, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 8417, 0, 2, rb_allocation::make_type1(99, 3), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block17.dat"}, {"test_data/pdsch_processor_test_output_grid17.dat"}}, - {{106, 14, {std::nullopt, {1, 7}, 28694, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 328, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 61255, 1, 2, rb_allocation::make_type1(67, 10), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block18.dat"}, {"test_data/pdsch_processor_test_output_grid18.dat"}}, - {{106, 14, {std::nullopt, {0, 7}, 9203, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 110, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 65010, 1, 2, rb_allocation::make_type1(50, 33), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(1))}}, {"test_data/pdsch_processor_test_input_transport_block19.dat"}, {"test_data/pdsch_processor_test_output_grid19.dat"}}, - {{106, 14, {std::nullopt, {0, 6}, 24678, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 531, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 37945, 1, 2, rb_allocation::make_type1(71, 11), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block20.dat"}, {"test_data/pdsch_processor_test_output_grid20.dat"}}, - {{106, 14, {std::nullopt, {1, 18}, 9579, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 449, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 22633, 0, 2, rb_allocation::make_type1(20, 20), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(1))}}, {"test_data/pdsch_processor_test_input_transport_block21.dat"}, {"test_data/pdsch_processor_test_output_grid21.dat"}}, - {{106, 14, {std::nullopt, {1, 18}, 32285, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 131, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 11781, 0, 2, rb_allocation::make_type1(11, 31), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block22.dat"}, {"test_data/pdsch_processor_test_output_grid22.dat"}}, - {{106, 14, {std::nullopt, {1, 3}, 7854, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 980, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 3160, 1, 2, rb_allocation::make_type1(30, 60), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block23.dat"}, {"test_data/pdsch_processor_test_output_grid23.dat"}}, + {{26, 14, {std::nullopt, {1, 20}, 59859, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 647, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 6392, 0, 2, rb_allocation::make_type1(24, 1), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block0.dat"}, {"test_data/pdsch_processor_test_output_grid0.dat"}}, + {{26, 14, {std::nullopt, {0, 10}, 25542, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 247, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 26470, 0, 2, rb_allocation::make_type1(23, 2), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(1))}}, {"test_data/pdsch_processor_test_input_transport_block1.dat"}, {"test_data/pdsch_processor_test_output_grid1.dat"}}, + {{26, 14, {std::nullopt, {1, 4}, 42422, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 556, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 47254, 1, 2, rb_allocation::make_type1(2, 3), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block2.dat"}, {"test_data/pdsch_processor_test_output_grid2.dat"}}, + {{26, 14, {std::nullopt, {0, 8}, 15757, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 701, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 55001, 1, 2, rb_allocation::make_type1(14, 5), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block3.dat"}, {"test_data/pdsch_processor_test_output_grid3.dat"}}, + {{26, 14, {std::nullopt, {1, 4}, 2632, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 238, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 23665, 1, 2, rb_allocation::make_type1(18, 7), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block4.dat"}, {"test_data/pdsch_processor_test_output_grid4.dat"}}, + {{26, 14, {std::nullopt, {0, 4}, 52060, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 909, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 9339, 1, 2, rb_allocation::make_type1(0, 6), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block5.dat"}, {"test_data/pdsch_processor_test_output_grid5.dat"}}, + {{26, 14, {std::nullopt, {1, 3}, 22295, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 335, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 40302, 1, 2, rb_allocation::make_type1(16, 7), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block6.dat"}, {"test_data/pdsch_processor_test_output_grid6.dat"}}, + {{26, 14, {std::nullopt, {1, 17}, 28483, 25, 1, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 524, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 34372, 0, 2, rb_allocation::make_type1(7, 13), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{1, 26, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 26, 2, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 26, 2, {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block7.dat"}, {"test_data/pdsch_processor_test_output_grid7.dat"}}, + {{54, 14, {std::nullopt, {1, 14}, 24782, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 782, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 3629, 0, 2, rb_allocation::make_type1(29, 10), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block8.dat"}, {"test_data/pdsch_processor_test_output_grid8.dat"}}, + {{54, 14, {std::nullopt, {1, 4}, 6544, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 761, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 11194, 1, 2, rb_allocation::make_type1(27, 16), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block9.dat"}, {"test_data/pdsch_processor_test_output_grid9.dat"}}, + {{54, 14, {std::nullopt, {1, 7}, 15603, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 149, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 52284, 1, 2, rb_allocation::make_type1(45, 4), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block10.dat"}, {"test_data/pdsch_processor_test_output_grid10.dat"}}, + {{54, 14, {std::nullopt, {1, 2}, 11901, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 576, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 8145, 1, 2, rb_allocation::make_type1(27, 15), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block11.dat"}, {"test_data/pdsch_processor_test_output_grid11.dat"}}, + {{54, 14, {std::nullopt, {1, 12}, 52353, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 228, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 3202, 1, 2, rb_allocation::make_type1(21, 23), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block12.dat"}, {"test_data/pdsch_processor_test_output_grid12.dat"}}, + {{54, 14, {std::nullopt, {1, 0}, 13972, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 586, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 2299, 0, 2, rb_allocation::make_type1(38, 5), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block13.dat"}, {"test_data/pdsch_processor_test_output_grid13.dat"}}, + {{54, 14, {std::nullopt, {0, 7}, 45487, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 879, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 55393, 1, 2, rb_allocation::make_type1(17, 17), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block14.dat"}, {"test_data/pdsch_processor_test_output_grid14.dat"}}, + {{54, 14, {std::nullopt, {1, 19}, 4550, 52, 2, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 685, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 15237, 0, 2, rb_allocation::make_type1(51, 1), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{2, 54, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {3, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {2, 54, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block15.dat"}, {"test_data/pdsch_processor_test_output_grid15.dat"}}, + {{106, 14, {std::nullopt, {1, 6}, 22402, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 476, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 54514, 0, 2, rb_allocation::make_type1(66, 10), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block16.dat"}, {"test_data/pdsch_processor_test_output_grid16.dat"}}, + {{106, 14, {std::nullopt, {1, 2}, 26011, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QPSK, 0}}, 740, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 8417, 0, 2, rb_allocation::make_type1(99, 3), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block17.dat"}, {"test_data/pdsch_processor_test_output_grid17.dat"}}, + {{106, 14, {std::nullopt, {1, 7}, 28694, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 328, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 61255, 1, 2, rb_allocation::make_type1(67, 10), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block18.dat"}, {"test_data/pdsch_processor_test_output_grid18.dat"}}, + {{106, 14, {std::nullopt, {0, 7}, 9203, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM16, 0}}, 110, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 65010, 1, 2, rb_allocation::make_type1(50, 33), 2, 12, ldpc_base_graph_type::BG2, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(1))}}, {"test_data/pdsch_processor_test_input_transport_block19.dat"}, {"test_data/pdsch_processor_test_output_grid19.dat"}}, + {{106, 14, {std::nullopt, {0, 6}, 24678, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 531, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 37945, 1, 2, rb_allocation::make_type1(71, 11), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(4))}}, {"test_data/pdsch_processor_test_input_transport_block20.dat"}, {"test_data/pdsch_processor_test_output_grid20.dat"}}, + {{106, 14, {std::nullopt, {1, 18}, 9579, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM64, 0}}, 449, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 22633, 0, 2, rb_allocation::make_type1(20, 20), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(1))}}, {"test_data/pdsch_processor_test_input_transport_block21.dat"}, {"test_data/pdsch_processor_test_output_grid21.dat"}}, + {{106, 14, {std::nullopt, {1, 18}, 32285, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 131, pdsch_processor::pdu_t::CRB0, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, dmrs_type::TYPE1, 11781, 0, 2, rb_allocation::make_type1(11, 31), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(3))}}, {"test_data/pdsch_processor_test_input_transport_block22.dat"}, {"test_data/pdsch_processor_test_output_grid22.dat"}}, + {{106, 14, {std::nullopt, {1, 3}, 7854, 106, 0, cyclic_prefix::NORMAL, {{modulation_scheme::QAM256, 0}}, 980, pdsch_processor::pdu_t::PRB0, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, dmrs_type::TYPE1, 3160, 1, 2, rb_allocation::make_type1(30, 60), 2, 12, ldpc_base_graph_type::BG1, units::bytes(159749), {{0, 106, 1, {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {1, 106, 2, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {0, 106, 2, {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}}, std::nullopt, 0, 0, precoding_configuration::make_wideband(make_identity(2))}}, {"test_data/pdsch_processor_test_input_transport_block23.dat"}, {"test_data/pdsch_processor_test_output_grid23.dat"}}, // clang-format on }; diff --git a/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_data.tar.gz b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_data.tar.gz new file mode 100644 index 0000000000..90c12b0a21 --- /dev/null +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_data.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4397386192c4a8480c67e6e4eed4d3d9f10cffac6f62d505ccf3b41dff102f4f +size 361556 diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_processor_test_doubles.h b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_doubles.h similarity index 95% rename from tests/unittests/phy/upper/channel_processors/pdsch_processor_test_doubles.h rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_doubles.h index 33072c4a88..fe231b71c4 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_processor_test_doubles.h +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_test_doubles.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include namespace srsran { diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_processor_unittest.cpp b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_unittest.cpp similarity index 97% rename from tests/unittests/phy/upper/channel_processors/pdsch_processor_unittest.cpp rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_unittest.cpp index edac7b0952..58992bcd33 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_processor_unittest.cpp +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_unittest.cpp @@ -8,16 +8,16 @@ * */ -#include "../../support/resource_grid_test_doubles.h" -#include "../signal_processors/dmrs_pdsch_processor_test_doubles.h" +#include "../../../support/resource_grid_test_doubles.h" +#include "../../signal_processors/dmrs_pdsch_processor_test_doubles.h" #include "pdsch_encoder_test_doubles.h" #include "pdsch_modulator_test_doubles.h" #include "pdsch_processor_test_doubles.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" -#include "srsran/phy/upper/channel_processors/pdsch_processor.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/pdsch_processor.h" #include "srsran/ran/precoding/precoding_codebooks.h" #include "srsran/srsvec/compare.h" -#include +#include "fmt/ostream.h" #include #include diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_processor_validator_test.cpp b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_validator_test.cpp similarity index 80% rename from tests/unittests/phy/upper/channel_processors/pdsch_processor_validator_test.cpp rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_validator_test.cpp index 1d47002cdc..715067182e 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_processor_validator_test.cpp +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_validator_test.cpp @@ -8,12 +8,13 @@ * */ -#include "../../support/resource_grid_mapper_test_doubles.h" -#include "../rx_buffer_test_doubles.h" +#include "../../../support/resource_grid_mapper_test_doubles.h" +#include "../../rx_buffer_test_doubles.h" #include "pdsch_processor_test_doubles.h" #include "srsran/phy/support/support_factories.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" #include "srsran/phy/upper/channel_processors/channel_processor_formatters.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/formatters.h" #include "srsran/ran/dmrs.h" #include "srsran/ran/precoding/precoding_codebooks.h" #include "fmt/ostream.h" @@ -24,29 +25,30 @@ using namespace srsran; namespace { // Valid PDSCH configuration used as a base for the test cases. -const pdsch_processor::pdu_t base_pdu = {std::nullopt, - {0, 19}, - 1, - 52, - 0, - cyclic_prefix::NORMAL, - {{modulation_scheme::QPSK, 0}}, - 1, - pdsch_processor::pdu_t::CRB0, - {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, - dmrs_type::TYPE1, - 0, - 0, - 1, - rb_allocation::make_type1(0, 52), - 2, - 12, - ldpc_base_graph_type::BG1, - units::bytes(3168), - {}, - 0, - 0, - precoding_configuration::make_wideband(make_single_port())}; +const pdsch_processor::pdu_t base_pdu = {.context = std::nullopt, + .slot = {0, 19}, + .rnti = 1, + .bwp_size_rb = 52, + .bwp_start_rb = 0, + .cp = cyclic_prefix::NORMAL, + .codewords = {{modulation_scheme::QPSK, 0}}, + .n_id = 1, + .ref_point = pdsch_processor::pdu_t::CRB0, + .dmrs_symbol_mask = {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, + .dmrs = dmrs_type::TYPE1, + .scrambling_id = 0, + .n_scid = 0, + .nof_cdm_groups_without_data = 1, + .freq_alloc = rb_allocation::make_type1(0, 52), + .start_symbol_index = 2, + .nof_symbols = 12, + .ldpc_base_graph = ldpc_base_graph_type::BG1, + .tbs_lbrm = units::bytes(3168), + .reserved = {}, + .ptrs = std::nullopt, + .ratio_pdsch_dmrs_to_sss_dB = 0, + .ratio_pdsch_data_to_sss_dB = 0, + .precoding = precoding_configuration::make_wideband(make_single_port())}; struct test_case_t { std::function get_pdu; @@ -55,7 +57,8 @@ struct test_case_t { std::ostream& operator<<(std::ostream& os, const test_case_t& test_case) { - fmt::print(os, "{}", test_case.get_pdu()); + pdsch_processor::pdu_t pdu = test_case.get_pdu(); + fmt::print(os, "{}", pdu); return os; } diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_processor_vectortest.cpp b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_vectortest.cpp similarity index 98% rename from tests/unittests/phy/upper/channel_processors/pdsch_processor_vectortest.cpp rename to tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_vectortest.cpp index 91d68e5440..0167e1f7c6 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch_processor_vectortest.cpp +++ b/tests/unittests/phy/upper/channel_processors/pdsch/pdsch_processor_vectortest.cpp @@ -8,15 +8,15 @@ * */ -#include "../../support/resource_grid_mapper_test_doubles.h" +#include "../../../support/resource_grid_mapper_test_doubles.h" #include "pdsch_processor_test_data.h" #include "pdsch_processor_test_doubles.h" #include "srsran/phy/support/support_factories.h" -#include "srsran/phy/upper/channel_processors/channel_processor_factories.h" #include "srsran/phy/upper/channel_processors/channel_processor_formatters.h" +#include "srsran/phy/upper/channel_processors/pdsch/factories.h" +#include "srsran/phy/upper/channel_processors/pdsch/formatters.h" #include "srsran/ran/pdsch/pdsch_constants.h" #include "srsran/support/executors/task_worker_pool.h" -#include "srsran/support/math_utils.h" #ifdef HWACC_PDSCH_ENABLED #include "srsran/hal/dpdk/bbdev/bbdev_acc.h" #include "srsran/hal/dpdk/bbdev/bbdev_acc_factory.h" diff --git a/tests/unittests/phy/upper/channel_processors/pdsch_processor_test_data.tar.gz b/tests/unittests/phy/upper/channel_processors/pdsch_processor_test_data.tar.gz deleted file mode 100644 index 882974da1c..0000000000 --- a/tests/unittests/phy/upper/channel_processors/pdsch_processor_test_data.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:141cf3e6d052b0223df7b9bf151d340380dd4d89f684344dd32a0e7fe57d365c -size 360333 diff --git a/tests/unittests/phy/upper/downlink_processor_test.cpp b/tests/unittests/phy/upper/downlink_processor_test.cpp index 1d33c3151a..0430bf9582 100644 --- a/tests/unittests/phy/upper/downlink_processor_test.cpp +++ b/tests/unittests/phy/upper/downlink_processor_test.cpp @@ -12,7 +12,7 @@ #include "../../support/task_executor_test_doubles.h" #include "../support/resource_grid_test_doubles.h" #include "channel_processors/pdcch_processor_test_doubles.h" -#include "channel_processors/pdsch_processor_test_doubles.h" +#include "channel_processors/pdsch/pdsch_processor_test_doubles.h" #include "channel_processors/ssb_processor_test_doubles.h" #include "signal_processors/nzp_csi_rs_generator_test_doubles.h" #include "upper_phy_rg_gateway_test_doubles.h" From 7cd7c67c8e158d8ecb10f003bb12d9dc13200772 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Wed, 11 Sep 2024 13:16:50 +0530 Subject: [PATCH 054/174] du_high,du_mgr: skip updating of UE dedicated configuration based on UE NR capabilities in test mode --- .../du/du_high/du_manager/du_manager_params.h | 13 +++++++------ lib/du/du_high/du_high_impl.cpp | 3 ++- lib/du/du_high/du_manager/du_manager_impl.cpp | 2 +- .../du_ran_resource_manager_impl.cpp | 10 +++++++--- .../du_ran_resource_manager_impl.h | 4 +++- .../du_manager/du_ran_resource_manager_test.cpp | 4 +++- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/srsran/du/du_high/du_manager/du_manager_params.h b/include/srsran/du/du_high/du_manager/du_manager_params.h index 90248ddecf..d2b8024d61 100644 --- a/include/srsran/du/du_high/du_manager/du_manager_params.h +++ b/include/srsran/du/du_high/du_manager/du_manager_params.h @@ -70,12 +70,13 @@ struct du_manager_params { scheduler_expert_config sched_cfg; }; - ran_params ran; - service_params services; - f1ap_config_params f1ap; - f1u_config_params f1u; - rlc_config_params rlc; - mac_config_params mac; + ran_params ran; + service_params services; + f1ap_config_params f1ap; + f1u_config_params f1u; + rlc_config_params rlc; + mac_config_params mac; + du_test_mode_config test_cfg; }; } // namespace srs_du diff --git a/lib/du/du_high/du_high_impl.cpp b/lib/du/du_high/du_high_impl.cpp index 7adf1720a5..e668cb4ce5 100644 --- a/lib/du/du_high/du_high_impl.cpp +++ b/lib/du/du_high/du_high_impl.cpp @@ -129,7 +129,8 @@ du_high_impl::du_high_impl(const du_high_configuration& config_) : {*f1ap, *f1ap}, {*config_.f1u_gw}, {mac->get_ue_control_info_handler(), *f1ap, *f1ap, *cfg.rlc_p, cfg.rlc_metrics_notif}, - {mac->get_cell_manager(), mac->get_ue_configurator(), cfg.ran.sched_cfg}}); + {mac->get_cell_manager(), mac->get_ue_configurator(), cfg.ran.sched_cfg}, + cfg.test_cfg}); // Connect Layer<->DU manager adapters. adapters->connect(*du_manager, *mac); diff --git a/lib/du/du_high/du_manager/du_manager_impl.cpp b/lib/du/du_high/du_manager/du_manager_impl.cpp index d14389c099..7f964761ae 100644 --- a/lib/du/du_high/du_manager/du_manager_impl.cpp +++ b/lib/du/du_high/du_manager/du_manager_impl.cpp @@ -23,7 +23,7 @@ du_manager_impl::du_manager_impl(const du_manager_params& params_) : params(params_), logger(srslog::fetch_basic_logger("DU-MNG")), cell_mng(params), - cell_res_alloc(params.ran.cells, params.mac.sched_cfg, params.ran.srbs, params.ran.qos), + cell_res_alloc(params.ran.cells, params.mac.sched_cfg, params.ran.srbs, params.ran.qos, params.test_cfg), ue_mng(params, cell_res_alloc), main_ctrl_loop(128) { diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp index a3667e1a32..5f29f08f91 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp @@ -41,9 +41,11 @@ du_ue_ran_resource_updater_impl::update(du_cell_index_t pc du_ran_resource_manager_impl::du_ran_resource_manager_impl(span cell_cfg_list_, const scheduler_expert_config& scheduler_cfg, const std::map& srb_config, - const std::map& qos_config) : + const std::map& qos_config, + const du_test_mode_config& test_cfg_) : cell_cfg_list(cell_cfg_list_), logger(srslog::fetch_basic_logger("DU-MNG")), + test_cfg(test_cfg_), pucch_res_mng(cell_cfg_list, scheduler_cfg.ue.max_pucchs_per_slot), bearer_res_mng(srb_config, qos_config, logger) { @@ -110,8 +112,10 @@ du_ran_resource_manager_impl::update_context(du_ue_index_t } } - // > Process UE NR capabilities and update UE dedicated configuration. - u.ue_cap_manager.update(ue_mcg, upd_req.ue_cap_rat_list); + // > Process UE NR capabilities and update UE dedicated configuration only if test mode is not configured. + if (not test_cfg.test_ue.has_value() or test_cfg.test_ue->rnti == rnti_t::INVALID_RNTI) { + u.ue_cap_manager.update(ue_mcg, upd_req.ue_cap_rat_list); + } // > Update UE SRBs and DRBs. du_ue_bearer_resource_update_response bearer_resp = diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h index d987015019..c4f0f65422 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h +++ b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h @@ -51,7 +51,8 @@ class du_ran_resource_manager_impl : public du_ran_resource_manager du_ran_resource_manager_impl(span cell_cfg_list_, const scheduler_expert_config& scheduler_cfg, const std::map& srbs, - const std::map& qos); + const std::map& qos, + const du_test_mode_config& test_cfg_); du_ran_resource_manager_impl(du_ran_resource_manager_impl&&) = delete; du_ran_resource_manager_impl(const du_ran_resource_manager_impl&) = delete; du_ran_resource_manager_impl& operator=(du_ran_resource_manager_impl&&) = delete; @@ -87,6 +88,7 @@ class du_ran_resource_manager_impl : public du_ran_resource_manager span cell_cfg_list; srslog::basic_logger& logger; + const du_test_mode_config& test_cfg; struct ue_resource_context { du_ue_resource_config cg_cfg; diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index fb8865308d..b1e8050b21 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -32,7 +32,8 @@ class du_ran_resource_manager_tester_base cell_cfg_list, scheduler_expert_config{.ue = {.max_pucchs_per_slot = max_pucch_grants}}, srb_cfg_list, - qos_cfg_list)) + qos_cfg_list, + dummy_test_mode_cfg)) { if (params.csi_rs_enabled) { default_csi_pucch_res_cfg = std::get( @@ -139,6 +140,7 @@ class du_ran_resource_manager_tester_base cell_config_builder_params params; du_cell_config du_cfg_param; + du_test_mode_config dummy_test_mode_cfg{}; std::vector cell_cfg_list; std::map srb_cfg_list; std::map qos_cfg_list; From dc2c2d0907a470e2d3dc024f6e4fe5d2be62f1ac Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 16 Sep 2024 15:47:08 +0200 Subject: [PATCH 055/174] ci: update retina --- .gitlab/ci/e2e/.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/e2e/.env b/.gitlab/ci/e2e/.env index 590ac61c0a..11e274921e 100644 --- a/.gitlab/ci/e2e/.env +++ b/.gitlab/ci/e2e/.env @@ -1,6 +1,6 @@ SRSGNB_REGISTRY_URI=registry.gitlab.com/softwareradiosystems/srsgnb RETINA_REGISTRY_PREFIX=registry.gitlab.com/softwareradiosystems/ci/retina -RETINA_VERSION=0.52.18 +RETINA_VERSION=0.52.19 UBUNTU_VERSION=24.04 AMARISOFT_VERSION=2023-09-08 SRSUE_VERSION=23.11 From 24c6e65207166d9bd55c5421ccf2e62a2ff6073c Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 16 Sep 2024 18:00:25 +0200 Subject: [PATCH 056/174] gnb: generate supported tas for test mode --- apps/gnb/gnb.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 9521f58ac9..f97ab916dc 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -234,9 +234,10 @@ int main(int argc, char** argv) autoderive_slicing_args(du_unit_cfg, cu_cp_config); autoderive_dynamic_du_parameters_after_parsing(app, du_unit_cfg); - // If test mode is enabled, we auto-enable "no_core" option + // If test mode is enabled, we auto-enable "no_core" option and generate a amf config with no core. if (du_unit_cfg.du_high_cfg.config.test_mode_cfg.test_ue.rnti != rnti_t::INVALID_RNTI) { - cu_cp_config.amf_config.no_core = true; + cu_cp_config.amf_config.no_core = true; + cu_cp_config.amf_config.amf.supported_tas = {{7, {{"00101", {s_nssai_t{1}}}}}}; } autoderive_cu_cp_parameters_after_parsing(app, cu_cp_config); From 00e2e33c83c97c56fa8b00b9d62d24cae57711b1 Mon Sep 17 00:00:00 2001 From: qarlosalberto Date: Tue, 17 Sep 2024 08:37:36 +0200 Subject: [PATCH 057/174] ci: adjust rlc_level log level --- tests/e2e/tests/viavi/test_declaration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index 9caeb9e201..d53b405b0e 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -199,7 +199,7 @@ tests: - campaign_filename: *campaign_filename test_name: "32UE ideal ping" test_timeout: *test_timeout - gnb_extra_commands: "log --all_level=info" + gnb_extra_commands: "log --all_level=info --rlc_level=warning" id: "32UE ideal ping" max_pdschs_per_slot: 1 max_puschs_per_slot: 4 From 2d67cef8663f3a24d1799affa086c91a198568a6 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 2 Sep 2024 11:22:08 +0200 Subject: [PATCH 058/174] sched,metrics: count full dl/ul slots, count ue prbs only during full slots --- include/srsran/scheduler/scheduler_metrics.h | 4 +++ .../logging/scheduler_metric_handler.cpp | 33 ++++++++++++++----- .../logging/scheduler_metrics_handler.h | 6 ++++ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/srsran/scheduler/scheduler_metrics.h b/include/srsran/scheduler/scheduler_metrics.h index 3789a139d3..c16b40074d 100644 --- a/include/srsran/scheduler/scheduler_metrics.h +++ b/include/srsran/scheduler/scheduler_metrics.h @@ -56,6 +56,10 @@ struct scheduler_cell_metrics { static constexpr unsigned nof_usec_per_bin = 50; /// Number of cell PRBs. unsigned nof_prbs = 0; + /// Number of full downlink slots. + unsigned nof_dl_slots = 0; + /// Number of full uplink slots. + unsigned nof_ul_slots = 0; unsigned nof_error_indications = 0; std::chrono::microseconds average_decision_latency{0}; diff --git a/lib/scheduler/logging/scheduler_metric_handler.cpp b/lib/scheduler/logging/scheduler_metric_handler.cpp index 39a4b8f638..80ce1611b8 100644 --- a/lib/scheduler/logging/scheduler_metric_handler.cpp +++ b/lib/scheduler/logging/scheduler_metric_handler.cpp @@ -198,11 +198,15 @@ void cell_metrics_handler::report_metrics() next_report.average_decision_latency = decision_latency_sum / report_period_slots; next_report.latency_histogram = decision_latency_hist; next_report.nof_prbs = nof_prbs; + next_report.nof_dl_slots = nof_dl_slots; + next_report.nof_ul_slots = nof_ul_slots; // Reset cell-wide metric counters. error_indication_counter = 0; decision_latency_sum = std::chrono::microseconds{0}; decision_latency_hist = {}; + nof_dl_slots = 0; + nof_ul_slots = 0; // Report all UE metrics in a batch. notifier.report_metrics(next_report); @@ -211,6 +215,10 @@ void cell_metrics_handler::report_metrics() void cell_metrics_handler::handle_slot_result(const sched_result& slot_result, std::chrono::microseconds slot_decision_latency) { + // Count only full DL/UL slots. + bool full_dl_slot = (slot_result.dl.nof_dl_symbols == 14); + bool full_ul_slot = (slot_result.ul.nof_ul_symbols == 14); + for (const dl_msg_alloc& dl_grant : slot_result.dl.ue_grants) { auto it = rnti_to_ue_index_lookup.find(dl_grant.pdsch_cfg.rnti); if (it == rnti_to_ue_index_lookup.end()) { @@ -223,11 +231,13 @@ void cell_metrics_handler::handle_slot_result(const sched_result& slot_res u.data.nof_dl_cws++; } if (dl_grant.pdsch_cfg.rbs.is_type0()) { - u.data.dl_prbs_used += - convert_rbgs_to_prbs(dl_grant.pdsch_cfg.rbs.type0(), {0, u.nof_prbs}, get_nominal_rbg_size(u.nof_prbs, true)) - .count(); + u.data.dl_prbs_used += full_dl_slot ? convert_rbgs_to_prbs(dl_grant.pdsch_cfg.rbs.type0(), + {0, u.nof_prbs}, + get_nominal_rbg_size(u.nof_prbs, true)) + .count() + : 0; } else if (dl_grant.pdsch_cfg.rbs.is_type1()) { - u.data.dl_prbs_used += (dl_grant.pdsch_cfg.rbs.type1().length()); + u.data.dl_prbs_used += full_dl_slot ? (dl_grant.pdsch_cfg.rbs.type1().length()) : 0; } } @@ -238,18 +248,23 @@ void cell_metrics_handler::handle_slot_result(const sched_result& slot_res continue; } if (ul_grant.pusch_cfg.rbs.is_type0()) { - ues[it->second].data.ul_prbs_used += convert_rbgs_to_prbs(ul_grant.pusch_cfg.rbs.type0(), - {0, ues[it->second].nof_prbs}, - get_nominal_rbg_size(ues[it->second].nof_prbs, true)) - .count(); + ues[it->second].data.ul_prbs_used += + full_ul_slot ? convert_rbgs_to_prbs(ul_grant.pusch_cfg.rbs.type0(), + {0, ues[it->second].nof_prbs}, + get_nominal_rbg_size(ues[it->second].nof_prbs, true)) + .count() + : 0; } else if (ul_grant.pusch_cfg.rbs.is_type1()) { - ues[it->second].data.ul_prbs_used += (ul_grant.pusch_cfg.rbs.type1().length()); + ues[it->second].data.ul_prbs_used += full_ul_slot ? (ul_grant.pusch_cfg.rbs.type1().length()) : 0; } ue_metric_context& u = ues[it->second]; u.data.ul_mcs += ul_grant.pusch_cfg.mcs_index.to_uint(); u.data.nof_puschs++; } + nof_dl_slots += full_dl_slot; + nof_ul_slots += full_ul_slot; + // Process latency. decision_latency_sum += slot_decision_latency; unsigned bin_idx = slot_decision_latency.count() / scheduler_cell_metrics::nof_usec_per_bin; diff --git a/lib/scheduler/logging/scheduler_metrics_handler.h b/lib/scheduler/logging/scheduler_metrics_handler.h index 374ef6b192..60618e914e 100644 --- a/lib/scheduler/logging/scheduler_metrics_handler.h +++ b/lib/scheduler/logging/scheduler_metrics_handler.h @@ -88,6 +88,12 @@ class cell_metrics_handler final : public harq_timeout_handler, public sched_met /// Number of the cell PRBs. unsigned nof_prbs = 0; + /// Number of full downlink slots. + unsigned nof_dl_slots = 0; + + /// Number of full uplink slots. + unsigned nof_ul_slots = 0; + /// Counter of number of slots elapsed since the last report. unsigned slot_counter = 0; From 1e894cdfc4a3a952f0281e2fc57eddd741922de8 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 2 Sep 2024 11:52:15 +0200 Subject: [PATCH 059/174] sched,metrics: cout total and mean ue prbs --- include/srsran/scheduler/scheduler_metrics.h | 6 +- .../e2sm_kpm_du_meas_provider_impl.cpp | 12 ++-- .../logging/scheduler_metric_handler.cpp | 69 ++++++++++--------- .../logging/scheduler_metrics_handler.h | 4 +- 4 files changed, 49 insertions(+), 42 deletions(-) diff --git a/include/srsran/scheduler/scheduler_metrics.h b/include/srsran/scheduler/scheduler_metrics.h index c16b40074d..5d2832a026 100644 --- a/include/srsran/scheduler/scheduler_metrics.h +++ b/include/srsran/scheduler/scheduler_metrics.h @@ -25,7 +25,8 @@ struct scheduler_ue_metrics { pci_t pci; rnti_t rnti; sch_mcs_index dl_mcs; - double dl_prbs_used; + unsigned tot_dl_prbs_used; + double mean_dl_prbs_used; double dl_brate_kbps; unsigned dl_nof_ok; unsigned dl_nof_nok; @@ -33,7 +34,8 @@ struct scheduler_ue_metrics { float pusch_rsrp_db; float pucch_snr_db; sch_mcs_index ul_mcs; - double ul_prbs_used; + unsigned tot_ul_prbs_used; + double mean_ul_prbs_used; double ul_brate_kbps; double ul_delay_ms; unsigned ul_nof_ok; diff --git a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp index 5a86fe3389..988b63bfb5 100644 --- a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp +++ b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp @@ -349,7 +349,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_avail_dl(const asn1::e2sm::label_in } int total_dl_prbs_used = std::accumulate( last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.dl_prbs_used; + return sum + metric.mean_dl_prbs_used; }); for (size_t i = 0; i < std::max(ues.size(), size_t(1)); ++i) { @@ -378,7 +378,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_avail_ul(const asn1::e2sm::label_in } int total_ul_prbs_used = std::accumulate( last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.ul_prbs_used; + return sum + metric.mean_ul_prbs_used; }); for (size_t i = 0; i < std::max(ues.size(), size_t(1)); ++i) { @@ -409,7 +409,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_dl(const asn1::e2sm::label if (ues.size() == 0) { int total_dl_prbs_used = std::accumulate( last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.dl_prbs_used; + return sum + metric.mean_dl_prbs_used; }); meas_record_item_c meas_record_item; meas_record_item.set_integer() = (double)total_dl_prbs_used * 100 / nof_cell_prbs; @@ -421,7 +421,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_dl(const asn1::e2sm::label gnb_cu_ue_f1ap_id_t gnb_cu_ue_f1ap_id = int_to_gnb_cu_ue_f1ap_id(ue.gnb_du_ue_id().gnb_cu_ue_f1ap_id); uint32_t ue_idx = f1ap_ue_id_provider.get_ue_index(gnb_cu_ue_f1ap_id); meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (double)last_ue_metrics[ue_idx].dl_prbs_used * 100 / nof_cell_prbs; + meas_record_item.set_integer() = (double)last_ue_metrics[ue_idx].mean_dl_prbs_used * 100 / nof_cell_prbs; items.push_back(meas_record_item); meas_collected = true; } @@ -446,7 +446,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_ul(const asn1::e2sm::label if (ues.size() == 0) { int total_ul_prbs_used = std::accumulate( last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.ul_prbs_used; + return sum + metric.mean_ul_prbs_used; }); meas_record_item_c meas_record_item; meas_record_item.set_integer() = (double)total_ul_prbs_used * 100 / nof_cell_prbs; @@ -458,7 +458,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_ul(const asn1::e2sm::label gnb_cu_ue_f1ap_id_t gnb_cu_ue_f1ap_id = int_to_gnb_cu_ue_f1ap_id(ue.gnb_du_ue_id().gnb_cu_ue_f1ap_id); uint32_t ue_idx = f1ap_ue_id_provider.get_ue_index(gnb_cu_ue_f1ap_id); meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (double)last_ue_metrics[ue_idx].ul_prbs_used * 100 / nof_cell_prbs; + meas_record_item.set_integer() = (double)last_ue_metrics[ue_idx].mean_ul_prbs_used * 100 / nof_cell_prbs; items.push_back(meas_record_item); meas_collected = true; } diff --git a/lib/scheduler/logging/scheduler_metric_handler.cpp b/lib/scheduler/logging/scheduler_metric_handler.cpp index 80ce1611b8..c9e8047f92 100644 --- a/lib/scheduler/logging/scheduler_metric_handler.cpp +++ b/lib/scheduler/logging/scheduler_metric_handler.cpp @@ -191,7 +191,12 @@ void cell_metrics_handler::report_metrics() for (ue_metric_context& ue : ues) { // Compute statistics of the UE metrics and push the result to the report. - next_report.ue_metrics.push_back(ue.compute_report(report_period)); + scheduler_ue_metrics sched_ue_metrics = ue.compute_report(report_period); + sched_ue_metrics.mean_dl_prbs_used = + nof_dl_slots > 0 ? static_cast(1.0 * sched_ue_metrics.tot_dl_prbs_used / nof_dl_slots) : 0; + sched_ue_metrics.mean_ul_prbs_used = + nof_ul_slots > 0 ? static_cast(1.0 * sched_ue_metrics.tot_ul_prbs_used / nof_ul_slots) : 0; + next_report.ue_metrics.push_back(sched_ue_metrics); } next_report.nof_error_indications = error_indication_counter; @@ -231,13 +236,13 @@ void cell_metrics_handler::handle_slot_result(const sched_result& slot_res u.data.nof_dl_cws++; } if (dl_grant.pdsch_cfg.rbs.is_type0()) { - u.data.dl_prbs_used += full_dl_slot ? convert_rbgs_to_prbs(dl_grant.pdsch_cfg.rbs.type0(), - {0, u.nof_prbs}, - get_nominal_rbg_size(u.nof_prbs, true)) - .count() - : 0; + u.data.tot_dl_prbs_used += full_dl_slot ? convert_rbgs_to_prbs(dl_grant.pdsch_cfg.rbs.type0(), + {0, u.nof_prbs}, + get_nominal_rbg_size(u.nof_prbs, true)) + .count() + : 0; } else if (dl_grant.pdsch_cfg.rbs.is_type1()) { - u.data.dl_prbs_used += full_dl_slot ? (dl_grant.pdsch_cfg.rbs.type1().length()) : 0; + u.data.tot_dl_prbs_used += full_dl_slot ? (dl_grant.pdsch_cfg.rbs.type1().length()) : 0; } } @@ -248,14 +253,14 @@ void cell_metrics_handler::handle_slot_result(const sched_result& slot_res continue; } if (ul_grant.pusch_cfg.rbs.is_type0()) { - ues[it->second].data.ul_prbs_used += + ues[it->second].data.tot_ul_prbs_used += full_ul_slot ? convert_rbgs_to_prbs(ul_grant.pusch_cfg.rbs.type0(), {0, ues[it->second].nof_prbs}, get_nominal_rbg_size(ues[it->second].nof_prbs, true)) .count() : 0; } else if (ul_grant.pusch_cfg.rbs.is_type1()) { - ues[it->second].data.ul_prbs_used += full_ul_slot ? (ul_grant.pusch_cfg.rbs.type1().length()) : 0; + ues[it->second].data.tot_ul_prbs_used += full_ul_slot ? (ul_grant.pusch_cfg.rbs.type1().length()) : 0; } ue_metric_context& u = ues[it->second]; u.data.ul_mcs += ul_grant.pusch_cfg.mcs_index.to_uint(); @@ -302,29 +307,29 @@ scheduler_ue_metrics cell_metrics_handler::ue_metric_context::compute_report(std::chrono::milliseconds metric_report_period) { scheduler_ue_metrics ret{}; - ret.pci = pci; - ret.rnti = rnti; - ret.cqi_stats = data.cqi; - ret.ri_stats = data.ri; - uint8_t mcs = data.nof_dl_cws > 0 ? std::roundf(static_cast(data.dl_mcs) / data.nof_dl_cws) : 0; - ret.dl_mcs = sch_mcs_index{mcs}; - mcs = data.nof_puschs > 0 ? std::roundf(static_cast(data.ul_mcs) / data.nof_puschs) : 0; - ret.ul_mcs = sch_mcs_index{mcs}; - ret.dl_prbs_used = static_cast(data.dl_prbs_used / (metric_report_period.count())); - ret.ul_prbs_used = static_cast(data.ul_prbs_used / (metric_report_period.count())); - ret.dl_brate_kbps = static_cast(data.sum_dl_tb_bytes * 8U) / metric_report_period.count(); - ret.ul_brate_kbps = static_cast(data.sum_ul_tb_bytes * 8U) / metric_report_period.count(); - ret.dl_nof_ok = data.count_uci_harq_acks; - ret.dl_nof_nok = data.count_uci_harqs - data.count_uci_harq_acks; - ret.ul_nof_ok = data.count_crc_acks; - ret.ul_nof_nok = data.count_crc_pdus - data.count_crc_acks; - ret.pusch_snr_db = data.nof_pusch_snr_reports > 0 ? data.sum_pusch_snrs / data.nof_pusch_snr_reports : 0; - ret.pusch_rsrp_db = data.nof_pusch_rsrp_reports > 0 ? data.sum_pusch_rsrp / data.nof_pusch_rsrp_reports - : -std::numeric_limits::infinity(); - ret.pucch_snr_db = data.nof_pucch_snr_reports > 0 ? data.sum_pucch_snrs / data.nof_pucch_snr_reports : 0; - ret.ul_delay_ms = data.sum_ul_delay_ms / data.count_crc_pdus; - ret.bsr = last_bsr; - ret.dl_bs = 0; + ret.pci = pci; + ret.rnti = rnti; + ret.cqi_stats = data.cqi; + ret.ri_stats = data.ri; + uint8_t mcs = data.nof_dl_cws > 0 ? std::roundf(static_cast(data.dl_mcs) / data.nof_dl_cws) : 0; + ret.dl_mcs = sch_mcs_index{mcs}; + mcs = data.nof_puschs > 0 ? std::roundf(static_cast(data.ul_mcs) / data.nof_puschs) : 0; + ret.ul_mcs = sch_mcs_index{mcs}; + ret.tot_dl_prbs_used = data.tot_dl_prbs_used; + ret.tot_ul_prbs_used = data.tot_ul_prbs_used; + ret.dl_brate_kbps = static_cast(data.sum_dl_tb_bytes * 8U) / metric_report_period.count(); + ret.ul_brate_kbps = static_cast(data.sum_ul_tb_bytes * 8U) / metric_report_period.count(); + ret.dl_nof_ok = data.count_uci_harq_acks; + ret.dl_nof_nok = data.count_uci_harqs - data.count_uci_harq_acks; + ret.ul_nof_ok = data.count_crc_acks; + ret.ul_nof_nok = data.count_crc_pdus - data.count_crc_acks; + ret.pusch_snr_db = data.nof_pusch_snr_reports > 0 ? data.sum_pusch_snrs / data.nof_pusch_snr_reports : 0; + ret.pusch_rsrp_db = data.nof_pusch_rsrp_reports > 0 ? data.sum_pusch_rsrp / data.nof_pusch_rsrp_reports + : -std::numeric_limits::infinity(); + ret.pucch_snr_db = data.nof_pucch_snr_reports > 0 ? data.sum_pucch_snrs / data.nof_pucch_snr_reports : 0; + ret.ul_delay_ms = data.sum_ul_delay_ms / data.count_crc_pdus; + ret.bsr = last_bsr; + ret.dl_bs = 0; for (const unsigned value : last_dl_bs) { ret.dl_bs += value; } diff --git a/lib/scheduler/logging/scheduler_metrics_handler.h b/lib/scheduler/logging/scheduler_metrics_handler.h index 60618e914e..4d91b2e40a 100644 --- a/lib/scheduler/logging/scheduler_metrics_handler.h +++ b/lib/scheduler/logging/scheduler_metrics_handler.h @@ -46,8 +46,8 @@ class cell_metrics_handler final : public harq_timeout_handler, public sched_met unsigned nof_pucch_snr_reports = 0; unsigned nof_pusch_snr_reports = 0; unsigned nof_pusch_rsrp_reports = 0; - unsigned dl_prbs_used = 0; - unsigned ul_prbs_used = 0; + unsigned tot_dl_prbs_used = 0; + unsigned tot_ul_prbs_used = 0; /// CQI statistics over the metrics report interval. sample_statistics cqi; /// RI statistics over the metrics report interval. From b91986e307b542a11c72954328673336c463e3f7 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 2 Sep 2024 12:01:22 +0200 Subject: [PATCH 060/174] e2sm,kpm: fix prb-based metrics --- .../e2sm_kpm_du_meas_provider_impl.cpp | 55 +++++++++++-------- .../e2sm_kpm/e2sm_kpm_du_meas_provider_impl.h | 2 + 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp index 988b63bfb5..761309131c 100644 --- a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp +++ b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp @@ -130,6 +130,9 @@ void e2sm_kpm_du_meas_provider_impl::report_metrics(const scheduler_cell_metrics { last_ue_metrics.clear(); nof_cell_prbs = cell_metrics.nof_prbs; + nof_dl_slots = cell_metrics.nof_dl_slots; + nof_ul_slots = cell_metrics.nof_ul_slots; + for (auto& ue_metric : cell_metrics.ue_metrics) { last_ue_metrics.push_back(ue_metric); } @@ -347,14 +350,16 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_avail_dl(const asn1::e2sm::label_in logger.debug("Metric: RRU.PrbAvailDl supports only NO_LABEL label."); return meas_collected; } - int total_dl_prbs_used = std::accumulate( - last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.mean_dl_prbs_used; - }); + int mean_dl_prbs_used = + std::accumulate(last_ue_metrics.begin(), + last_ue_metrics.end(), + 0, + [](size_t sum, const scheduler_ue_metrics& metric) { return sum + metric.tot_dl_prbs_used; }) / + nof_dl_slots; for (size_t i = 0; i < std::max(ues.size(), size_t(1)); ++i) { meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (nof_cell_prbs - total_dl_prbs_used); + meas_record_item.set_integer() = (nof_cell_prbs - mean_dl_prbs_used); items.push_back(meas_record_item); meas_collected = true; } @@ -376,14 +381,16 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_avail_ul(const asn1::e2sm::label_in logger.debug("Metric: RRU.PrbAvailUl supports only NO_LABEL label."); return meas_collected; } - int total_ul_prbs_used = std::accumulate( - last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.mean_ul_prbs_used; - }); + int mean_ul_prbs_used = + std::accumulate(last_ue_metrics.begin(), + last_ue_metrics.end(), + 0, + [](size_t sum, const scheduler_ue_metrics& metric) { return sum + metric.tot_ul_prbs_used; }) / + nof_ul_slots; for (size_t i = 0; i < std::max(ues.size(), size_t(1)); ++i) { meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (nof_cell_prbs - total_ul_prbs_used); + meas_record_item.set_integer() = (nof_cell_prbs - mean_ul_prbs_used); items.push_back(meas_record_item); meas_collected = true; } @@ -407,12 +414,14 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_dl(const asn1::e2sm::label } if (ues.size() == 0) { - int total_dl_prbs_used = std::accumulate( - last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.mean_dl_prbs_used; - }); + double mean_dl_prbs_used = + std::accumulate(last_ue_metrics.begin(), + last_ue_metrics.end(), + 0, + [](size_t sum, const scheduler_ue_metrics& metric) { return sum + metric.tot_dl_prbs_used; }) / + nof_dl_slots; meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (double)total_dl_prbs_used * 100 / nof_cell_prbs; + meas_record_item.set_integer() = mean_dl_prbs_used * 100 / nof_cell_prbs; items.push_back(meas_record_item); meas_collected = true; } @@ -421,7 +430,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_dl(const asn1::e2sm::label gnb_cu_ue_f1ap_id_t gnb_cu_ue_f1ap_id = int_to_gnb_cu_ue_f1ap_id(ue.gnb_du_ue_id().gnb_cu_ue_f1ap_id); uint32_t ue_idx = f1ap_ue_id_provider.get_ue_index(gnb_cu_ue_f1ap_id); meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (double)last_ue_metrics[ue_idx].mean_dl_prbs_used * 100 / nof_cell_prbs; + meas_record_item.set_integer() = last_ue_metrics[ue_idx].mean_dl_prbs_used * 100 / nof_cell_prbs; items.push_back(meas_record_item); meas_collected = true; } @@ -444,12 +453,14 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_ul(const asn1::e2sm::label return meas_collected; } if (ues.size() == 0) { - int total_ul_prbs_used = std::accumulate( - last_ue_metrics.begin(), last_ue_metrics.end(), 0, [](size_t sum, const scheduler_ue_metrics& metric) { - return sum + metric.mean_ul_prbs_used; - }); + double mean_ul_prbs_used = + std::accumulate(last_ue_metrics.begin(), + last_ue_metrics.end(), + 0, + [](size_t sum, const scheduler_ue_metrics& metric) { return sum + metric.tot_ul_prbs_used; }) / + nof_ul_slots; meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (double)total_ul_prbs_used * 100 / nof_cell_prbs; + meas_record_item.set_integer() = mean_ul_prbs_used * 100 / nof_cell_prbs; items.push_back(meas_record_item); meas_collected = true; } @@ -458,7 +469,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_ul(const asn1::e2sm::label gnb_cu_ue_f1ap_id_t gnb_cu_ue_f1ap_id = int_to_gnb_cu_ue_f1ap_id(ue.gnb_du_ue_id().gnb_cu_ue_f1ap_id); uint32_t ue_idx = f1ap_ue_id_provider.get_ue_index(gnb_cu_ue_f1ap_id); meas_record_item_c meas_record_item; - meas_record_item.set_integer() = (double)last_ue_metrics[ue_idx].mean_ul_prbs_used * 100 / nof_cell_prbs; + meas_record_item.set_integer() = last_ue_metrics[ue_idx].mean_ul_prbs_used * 100 / nof_cell_prbs; items.push_back(meas_record_item); meas_collected = true; } diff --git a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.h b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.h index 94f088d8f8..5be204776e 100644 --- a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.h +++ b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.h @@ -108,6 +108,8 @@ class e2sm_kpm_du_meas_provider_impl : public e2sm_kpm_meas_provider, public e2_ srslog::basic_logger& logger; srs_du::f1ap_ue_id_translator& f1ap_ue_id_provider; unsigned nof_cell_prbs; + unsigned nof_dl_slots; + unsigned nof_ul_slots; std::vector last_ue_metrics; std::map> ue_aggr_rlc_metrics; size_t max_rlc_metrics = 1; From b2459ed6e76fb2969b754b0355441c7a463def02 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 2 Sep 2024 13:10:40 +0200 Subject: [PATCH 061/174] e2sm,kpm: change condition ues.size() == 0 -> ues.empty() --- .../e2sm_kpm_du_meas_provider_impl.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp index 761309131c..271a40112c 100644 --- a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp +++ b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp @@ -413,7 +413,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_dl(const asn1::e2sm::label return meas_collected; } - if (ues.size() == 0) { + if (ues.empty()) { double mean_dl_prbs_used = std::accumulate(last_ue_metrics.begin(), last_ue_metrics.end(), @@ -452,7 +452,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_prb_use_perc_ul(const asn1::e2sm::label logger.debug("Metric: RRU.PrbTotUl supports only NO_LABEL label."); return meas_collected; } - if (ues.size() == 0) { + if (ues.empty()) { double mean_ul_prbs_used = std::accumulate(last_ue_metrics.begin(), last_ue_metrics.end(), @@ -551,7 +551,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_dl_mean_throughput(const asn1::e2sm (float)1000; ue_throughput[ue.first] = bytes_to_kbits(num_pdu_bytes_no_segmentation + num_pdu_bytes_with_segmentation) / seconds; } - if (ues.size() == 0) { + if (ues.empty()) { meas_record_item_c meas_record_item; int total_throughput = 0; for (auto& ue : ue_throughput) { @@ -606,7 +606,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_ul_mean_throughput(const asn1::e2sm (float)1000; ue_throughput[ue.first] = bytes_to_kbits(num_pdu_bytes) / seconds; // unit is kbps } - if (ues.size() == 0) { + if (ues.empty()) { meas_record_item_c meas_record_item; int total_throughput = 0; for (auto& ue : ue_throughput) { @@ -651,7 +651,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_ul_success_rate(const asn1::e2sm::l if (cell_global_id.has_value()) { logger.debug("Metric: DRB.PacketSuccessRateUlgNBUu currently does not support cell_global_id filter."); } - if (ues.size() == 0) { + if (ues.empty()) { // E2 level measurements. meas_record_item_c meas_record_item; float success_rate = 0; @@ -731,7 +731,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_rlc_packet_drop_rate_dl( logger.debug("Metric: DRB.RlcPacketDropRateDl currently does not support cell_global_id filter."); } - if (ues.size() == 0) { + if (ues.empty()) { // E2 level measurements. meas_record_item_c meas_record_item; float drop_rate = 0; @@ -812,7 +812,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_rlc_sdu_transmitted_volume_dl( logger.debug("Metric: DRB.RlcSduTransmittedVolumeDL currently does not support cell_global_id filter."); } - if (ues.size() == 0) { + if (ues.empty()) { // E2 level measurements. meas_record_item_c meas_record_item; size_t total_tx_num_sdu_bytes = 0; @@ -871,7 +871,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_rlc_sdu_transmitted_volume_ul( logger.debug("Metric: DRB.RlcSduTransmittedVolumeUL currently does not support cell_global_id filter."); } - if (ues.size() == 0) { + if (ues.empty()) { // E2 level measurements. meas_record_item_c meas_record_item; size_t total_rx_num_sdu_bytes = 0; @@ -925,7 +925,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_dl_rlc_sdu_latency(const asn1::e2sm return meas_collected; } - if (ues.size() == 0) { + if (ues.empty()) { meas_record_item_c meas_record_item; float av_ue_sdu_latency_us = 0; for (auto& rlc_metric : ue_aggr_rlc_metrics) { @@ -1000,7 +1000,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_ul_rlc_sdu_latency(const asn1::e2sm return meas_collected; } - if (ues.size() == 0) { + if (ues.empty()) { meas_record_item_c meas_record_item; float av_ue_sdu_latency_us = 0; for (auto& rlc_metric : ue_aggr_rlc_metrics) { From 9b75b87bd4c9e1f9454f684d2f691c0833262105 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 2 Sep 2024 13:30:32 +0200 Subject: [PATCH 062/174] e2sm,kpm: fix e2-node-level DRB.UEThpDl and DRB.UEThpUl values --- lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp index 271a40112c..cfe80be5d3 100644 --- a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp +++ b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp @@ -557,7 +557,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_dl_mean_throughput(const asn1::e2sm for (auto& ue : ue_throughput) { total_throughput += ue.second; } - meas_record_item.set_integer() = total_throughput / ue_throughput.size(); + meas_record_item.set_integer() = total_throughput; items.push_back(meas_record_item); meas_collected = true; } @@ -612,7 +612,7 @@ bool e2sm_kpm_du_meas_provider_impl::get_drb_ul_mean_throughput(const asn1::e2sm for (auto& ue : ue_throughput) { total_throughput += ue.second; } - meas_record_item.set_integer() = total_throughput / ue_throughput.size(); + meas_record_item.set_integer() = total_throughput; items.push_back(meas_record_item); meas_collected = true; } From bbfeb95aca5e7cbbe2ec35a9de7f848642d07764 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 16 Sep 2024 17:43:00 +0200 Subject: [PATCH 063/174] sched,test: set nof_dl_symbols/nof_ul_symbols value --- .../scheduler/scheduler_metrics_handler_test.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/unittests/scheduler/scheduler_metrics_handler_test.cpp b/tests/unittests/scheduler/scheduler_metrics_handler_test.cpp index 5f30ee0076..3b87476321 100644 --- a/tests/unittests/scheduler/scheduler_metrics_handler_test.cpp +++ b/tests/unittests/scheduler/scheduler_metrics_handler_test.cpp @@ -43,6 +43,8 @@ class scheduler_metrics_handler_tester : public ::testing::Test { metrics_notif.last_report = {}; sched_result sched_res; + sched_res.dl.nof_dl_symbols = 14; + sched_res.ul.nof_ul_symbols = 14; while (metrics_notif.last_report.ue_metrics.empty()) { run_slot(sched_res); } @@ -157,7 +159,9 @@ TEST_F(scheduler_metrics_handler_tester, compute_mcs) sch_mcs_index dl_mcs{test_rgen::uniform_int(1, 28)}; sch_mcs_index ul_mcs{test_rgen::uniform_int(1, 28)}; - sched_result res; + sched_result res; + res.dl.nof_dl_symbols = 14; + res.ul.nof_ul_symbols = 14; dl_msg_alloc& dl_msg = res.dl.ue_grants.emplace_back(); dl_msg.pdsch_cfg.rnti = to_rnti(0x4601); auto& cw = dl_msg.pdsch_cfg.codewords.emplace_back(); @@ -230,6 +234,9 @@ TEST_F(scheduler_metrics_handler_tester, compute_latency_metric) samples.resize(report_period.count()); sched_result sched_res; + sched_res.dl.nof_dl_symbols = 14; + sched_res.ul.nof_ul_symbols = 14; + for (unsigned i = 0; i != samples.size(); ++i) { ASSERT_TRUE(metrics_notif.last_report.ue_metrics.empty()); this->run_slot(sched_res, samples[i]); From 0cc17cb061281e760f6e6a1bd432c189c109d0a3 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 17 Sep 2024 10:26:46 +0200 Subject: [PATCH 064/174] ru_dummy: parametrized time scaling ru_dummy: review documentation ru_dummy: review scaling time --- .../split_dynamic/dynamic_du_translators.cpp | 1 + .../split_dynamic/dynamic_du_unit_cli11_schema.cpp | 7 +++++++ .../flexible_du/split_dynamic/dynamic_du_unit_config.h | 10 ++++++++++ .../dynamic_du_unit_config_yaml_writer.cpp | 1 + include/srsran/ru/ru_dummy_configuration.h | 2 ++ lib/ru/dummy/ru_dummy_impl.cpp | 5 ++--- 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp index db173200d0..99ce0bcb5c 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp @@ -35,6 +35,7 @@ ru_dummy_configuration srsran::generate_ru_dummy_config(const ru_dummy_unit_conf out_cfg.rx_prach_nof_ports = nof_prach_ports; out_cfg.max_processing_delay_slots = max_processing_delay_slots; out_cfg.dl_processing_delay = ru_cfg.dl_processing_delay; + out_cfg.time_scaling = ru_cfg.time_scaling; return out_cfg; } diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp index 64aa68b409..203930abb5 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp @@ -29,6 +29,13 @@ static void configure_cli11_ru_dummy_args(CLI::App& app, ru_dummy_unit_config& c { add_option(app, "--dl_processing_delay", config.dl_processing_delay, "DL processing processing delay in slots") ->capture_default_str(); + add_option(app, + "--time_scaling", + config.time_scaling, + "Time scaling factor applied to the slot duration. Must be greater than zero. " + "A value greater than one slows down the RU, while a value between zero and one speeds it up.") + ->capture_default_str() + ->check(CLI::NonNegativeNumber); } static void configure_cli11_cell_affinity_args(CLI::App& app, ru_dummy_cpu_affinities_cell_unit_config& config) diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h index 81dc809670..20b41186d1 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h @@ -32,6 +32,16 @@ struct ru_dummy_unit_config { /// It is the number of slots that the RU expects the downlink resource grid in advance for having enough time margin /// for processing. unsigned dl_processing_delay = 1; + /// \brief Time scaling factor applied to the slot duration based on the subcarrier spacing. + /// + /// This attribute adjusts the slot duration by scaling it: + /// + /// - A value below one shortens the slot duration. + /// - A value above one increases the slot duration. + /// - A value of one maintains the default slot duration. + /// + /// The default value of 1.0 corresponds to the standard slot duration with no scaling applied. + float time_scaling = 1.0F; /// \brief CPU affinities per cell of the SDR Radio Unit. /// /// \note Add one cell by default. diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp index 4d51b30726..937f5c776a 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp @@ -22,6 +22,7 @@ static void fill_ru_dummy_config(YAML::Node node, const ru_dummy_unit_config& co { auto ru_dummy_node = node["ru_dummy"]; ru_dummy_node["dl_processing_delay"] = config.dl_processing_delay; + ru_dummy_node["time_scaling"] = config.time_scaling; auto expert_exec_node = node["expert_execution"]; diff --git a/include/srsran/ru/ru_dummy_configuration.h b/include/srsran/ru/ru_dummy_configuration.h index 3298124bee..885a382567 100644 --- a/include/srsran/ru/ru_dummy_configuration.h +++ b/include/srsran/ru/ru_dummy_configuration.h @@ -36,6 +36,8 @@ struct ru_dummy_configuration { unsigned max_processing_delay_slots; /// DL processing processing delay in slots. See \ref ru_dummy_appconfig::dl_processing_delay for more information. unsigned dl_processing_delay; + /// Time scaling, \ref ru_dummy_unit_config::time_scaling for more details. + float time_scaling; }; /// Collects the necessary dependencies for the dummy radio unit. diff --git a/lib/ru/dummy/ru_dummy_impl.cpp b/lib/ru/dummy/ru_dummy_impl.cpp index 68a74385f0..729578aff9 100644 --- a/lib/ru/dummy/ru_dummy_impl.cpp +++ b/lib/ru/dummy/ru_dummy_impl.cpp @@ -30,12 +30,11 @@ static inline uint64_t get_current_system_slot(std::chrono::microseconds slot_du return (time_since_epoch / slot_duration) % nof_slots_per_system_frame; } -ru_dummy_impl::ru_dummy_impl(const srsran::ru_dummy_configuration& config, ru_dummy_dependencies dependencies) noexcept - : +ru_dummy_impl::ru_dummy_impl(const ru_dummy_configuration& config, ru_dummy_dependencies dependencies) noexcept : logger(*dependencies.logger), executor(*dependencies.executor), timing_notifier(*dependencies.timing_notifier), - slot_duration(1000 / pow2(to_numerology_value(config.scs))), + slot_duration(static_cast(config.time_scaling * 1000.0 / pow2(to_numerology_value(config.scs)))), max_processing_delay_slots(config.max_processing_delay_slots), current_slot(config.scs, config.max_processing_delay_slots) { From de80dc12b757762a74fb6d9ccac33c5606596d5e Mon Sep 17 00:00:00 2001 From: qarlosalberto Date: Tue, 17 Sep 2024 14:42:26 +0200 Subject: [PATCH 065/174] ci: update retina --- .gitlab/ci/e2e/.env | 2 +- tests/e2e/tests/test_mode/config_ru.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab/ci/e2e/.env b/.gitlab/ci/e2e/.env index 11e274921e..3acd758a4d 100644 --- a/.gitlab/ci/e2e/.env +++ b/.gitlab/ci/e2e/.env @@ -1,6 +1,6 @@ SRSGNB_REGISTRY_URI=registry.gitlab.com/softwareradiosystems/srsgnb RETINA_REGISTRY_PREFIX=registry.gitlab.com/softwareradiosystems/ci/retina -RETINA_VERSION=0.52.19 +RETINA_VERSION=0.52.20 UBUNTU_VERSION=24.04 AMARISOFT_VERSION=2023-09-08 SRSUE_VERSION=23.11 diff --git a/tests/e2e/tests/test_mode/config_ru.yml b/tests/e2e/tests/test_mode/config_ru.yml index 09a0e1a193..7d737fd221 100644 --- a/tests/e2e/tests/test_mode/config_ru.yml +++ b/tests/e2e/tests/test_mode/config_ru.yml @@ -34,6 +34,7 @@ cells: - pci: 1 ru_dummy: + time_scaling: 10 test_mode: test_ue: From bcf5ee2611cd49cd8a60775a87612a96bb613bd4 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 17 Sep 2024 10:26:08 +0200 Subject: [PATCH 066/174] sched: avoid race condition in access to last slot in ue_event_manager --- lib/scheduler/ue_scheduling/ue_event_manager.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.cpp b/lib/scheduler/ue_scheduling/ue_event_manager.cpp index 19d52b4641..73ad3a9f83 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.cpp +++ b/lib/scheduler/ue_scheduling/ue_event_manager.cpp @@ -325,11 +325,10 @@ void ue_event_manager::handle_ul_phr_indication(const ul_phr_indication_message& void ue_event_manager::handle_crc_indication(const ul_crc_indication& crc_ind) { srsran_assert(cell_exists(crc_ind.cell_index), "Invalid cell index"); - int slot_delay = last_sl - crc_ind.sl_rx; for (unsigned i = 0, e = crc_ind.crcs.size(); i != e; ++i) { cell_specific_events[crc_ind.cell_index].emplace( crc_ind.crcs[i].ue_index, - [this, slot_delay, sl_rx = crc_ind.sl_rx, crc = crc_ind.crcs[i]](ue_cell& ue_cc) { + [this, sl_rx = crc_ind.sl_rx, crc = crc_ind.crcs[i]](ue_cell& ue_cc) { const int tbs = ue_cc.handle_crc_pdu(sl_rx, crc); if (tbs < 0) { return; @@ -347,7 +346,7 @@ void ue_event_manager::handle_crc_indication(const ul_crc_indication& crc_ind) // Notify metrics handler. metrics_handler.handle_crc_indication(crc, units::bytes{(unsigned)tbs}); - metrics_handler.handle_ul_delay(crc.ue_index, slot_delay); + metrics_handler.handle_ul_delay(crc.ue_index, last_sl - sl_rx); }, "CRC", true); From 10541f24dcd5c882a0e2187ca21177df780369a6 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 17 Sep 2024 11:52:05 +0200 Subject: [PATCH 067/174] e2sm_kpm: fix ue filter --- .../e2sm_kpm_du_meas_provider_impl.cpp | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp index cfe80be5d3..bdb9314bd8 100644 --- a/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp +++ b/lib/e2/e2sm/e2sm_kpm/e2sm_kpm_du_meas_provider_impl.cpp @@ -204,13 +204,16 @@ bool e2sm_kpm_du_meas_provider_impl::get_ues_matching_test_conditions( { // TODO: add test condition checking, now return all UEs for (const auto& ue : ue_aggr_rlc_metrics) { - du_ue_index_t ue_index = to_du_ue_index(ue.first); - ue_id_c ueid; - ue_id_gnb_du_s ueid_gnb_du{}; + du_ue_index_t ue_index = to_du_ue_index(ue.first); gnb_cu_ue_f1ap_id_t gnb_cu_ue_f1ap_id = f1ap_ue_id_provider.get_gnb_cu_ue_f1ap_id(ue_index); - ueid_gnb_du.gnb_cu_ue_f1ap_id = gnb_cu_ue_f1ap_id_to_uint(gnb_cu_ue_f1ap_id); - ueid_gnb_du.ran_ue_id_present = false; - ueid.set_gnb_du_ue_id() = ueid_gnb_du; + if (gnb_cu_ue_f1ap_id == gnb_cu_ue_f1ap_id_t::invalid) { + continue; + } + ue_id_c ueid; + ue_id_gnb_du_s ueid_gnb_du{}; + ueid_gnb_du.gnb_cu_ue_f1ap_id = gnb_cu_ue_f1ap_id_to_uint(gnb_cu_ue_f1ap_id); + ueid_gnb_du.ran_ue_id_present = false; + ueid.set_gnb_du_ue_id() = ueid_gnb_du; ues.push_back(ueid); } @@ -223,13 +226,16 @@ bool e2sm_kpm_du_meas_provider_impl::get_ues_matching_test_conditions( { // TODO: add test condition checking, now return all UEs for (const auto& ue : ue_aggr_rlc_metrics) { - du_ue_index_t ue_index = to_du_ue_index(ue.first); - ue_id_c ueid; - ue_id_gnb_du_s ueid_gnb_du{}; + du_ue_index_t ue_index = to_du_ue_index(ue.first); gnb_cu_ue_f1ap_id_t gnb_cu_ue_f1ap_id = f1ap_ue_id_provider.get_gnb_cu_ue_f1ap_id(ue_index); - ueid_gnb_du.gnb_cu_ue_f1ap_id = gnb_cu_ue_f1ap_id_to_uint(gnb_cu_ue_f1ap_id); - ueid_gnb_du.ran_ue_id_present = false; - ueid.set_gnb_du_ue_id() = ueid_gnb_du; + if (gnb_cu_ue_f1ap_id == gnb_cu_ue_f1ap_id_t::invalid) { + continue; + } + ue_id_c ueid; + ue_id_gnb_du_s ueid_gnb_du{}; + ueid_gnb_du.gnb_cu_ue_f1ap_id = gnb_cu_ue_f1ap_id_to_uint(gnb_cu_ue_f1ap_id); + ueid_gnb_du.ran_ue_id_present = false; + ueid.set_gnb_du_ue_id() = ueid_gnb_du; ues.push_back(ueid); } From caff5854bf7e6d44a60b5e98733280ab34c6e46b Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Thu, 12 Sep 2024 14:09:18 +0530 Subject: [PATCH 068/174] sched: move resource grid utility functions under include --- .../cell => include/srsran/scheduler}/resource_grid_util.h | 0 lib/scheduler/cell/cell_harq_manager.cpp | 2 +- lib/scheduler/cell/resource_grid.h | 2 +- lib/scheduler/uci_scheduling/uci_scheduler_impl.h | 2 +- lib/scheduler/ue_scheduling/ue_repository.cpp | 2 +- tests/unittests/scheduler/scheduler_ue_removal_test.cpp | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename {lib/scheduler/cell => include/srsran/scheduler}/resource_grid_util.h (100%) diff --git a/lib/scheduler/cell/resource_grid_util.h b/include/srsran/scheduler/resource_grid_util.h similarity index 100% rename from lib/scheduler/cell/resource_grid_util.h rename to include/srsran/scheduler/resource_grid_util.h diff --git a/lib/scheduler/cell/cell_harq_manager.cpp b/lib/scheduler/cell/cell_harq_manager.cpp index 04587bcef0..57dee83bdf 100644 --- a/lib/scheduler/cell/cell_harq_manager.cpp +++ b/lib/scheduler/cell/cell_harq_manager.cpp @@ -9,7 +9,7 @@ */ #include "cell_harq_manager.h" -#include "resource_grid_util.h" +#include "srsran/scheduler/resource_grid_util.h" #include "srsran/scheduler/scheduler_slot_handler.h" using namespace srsran; diff --git a/lib/scheduler/cell/resource_grid.h b/lib/scheduler/cell/resource_grid.h index ec6e4e10cb..a86771ad60 100644 --- a/lib/scheduler/cell/resource_grid.h +++ b/lib/scheduler/cell/resource_grid.h @@ -13,10 +13,10 @@ #include "../config/cell_configuration.h" #include "../support/bwp_helpers.h" #include "../support/rb_helper.h" -#include "resource_grid_util.h" #include "srsran/adt/circular_array.h" #include "srsran/ran/slot_point.h" #include "srsran/scheduler/mac_scheduler.h" +#include "srsran/scheduler/resource_grid_util.h" namespace srsran { diff --git a/lib/scheduler/uci_scheduling/uci_scheduler_impl.h b/lib/scheduler/uci_scheduling/uci_scheduler_impl.h index 5099755660..d22a9fc1d6 100644 --- a/lib/scheduler/uci_scheduling/uci_scheduler_impl.h +++ b/lib/scheduler/uci_scheduling/uci_scheduler_impl.h @@ -10,9 +10,9 @@ #pragma once -#include "../cell/resource_grid_util.h" #include "../ue_scheduling/ue_repository.h" #include "uci_scheduler.h" +#include "srsran/scheduler/resource_grid_util.h" namespace srsran { diff --git a/lib/scheduler/ue_scheduling/ue_repository.cpp b/lib/scheduler/ue_scheduling/ue_repository.cpp index df00616e42..642fe488f4 100644 --- a/lib/scheduler/ue_scheduling/ue_repository.cpp +++ b/lib/scheduler/ue_scheduling/ue_repository.cpp @@ -9,7 +9,7 @@ */ #include "ue_repository.h" -#include "../cell/resource_grid_util.h" +#include "srsran/scheduler/resource_grid_util.h" #include "srsran/srslog/srslog.h" using namespace srsran; diff --git a/tests/unittests/scheduler/scheduler_ue_removal_test.cpp b/tests/unittests/scheduler/scheduler_ue_removal_test.cpp index 90557f0d26..ec91bca00c 100644 --- a/tests/unittests/scheduler/scheduler_ue_removal_test.cpp +++ b/tests/unittests/scheduler/scheduler_ue_removal_test.cpp @@ -11,10 +11,10 @@ /// \file /// \brief In this file, we test the correct behaviour of the scheduler when removing UEs. -#include "lib/scheduler/cell/resource_grid_util.h" #include "test_utils/config_generators.h" #include "test_utils/result_test_helpers.h" #include "test_utils/scheduler_test_bench.h" +#include "srsran/scheduler/resource_grid_util.h" #include using namespace srsran; From 2c70ea6b9fad5f15aa3ba09c9a296b27716651e4 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Thu, 12 Sep 2024 14:26:27 +0530 Subject: [PATCH 069/174] du_high: fix scheduler decision history ring size when using test mode --- lib/du/du_high/adapters/mac_test_mode_adapter.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp index 9c8aa87a4f..fe30fb626f 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp @@ -14,6 +14,7 @@ #include "srsran/mac/mac_factory.h" #include "srsran/ran/csi_report/csi_report_on_pucch_helpers.h" #include "srsran/scheduler/harq_id.h" +#include "srsran/scheduler/resource_grid_util.h" #include #include @@ -90,11 +91,13 @@ mac_test_mode_cell_adapter::mac_test_mode_cell_adapter( logger(srslog::fetch_basic_logger("MAC")), ue_info_mgr(ue_info_mgr_) { - // Note: The history ring size has to be a multiple of the TDD frame size in slots. - const size_t HISTORY_RING_SIZE = - 100 * (cell_cfg.sched_req.tdd_ul_dl_cfg_common.has_value() - ? nof_slots_per_tdd_period(cell_cfg.sched_req.tdd_ul_dl_cfg_common.value()) - : 10U); + /// \brief Number of previous slot results to keep in history before they get deleted. + /// + /// Having access to past decisions is useful during the handling of error indications. + static const size_t RING_MAX_HISTORY_SIZE = 8; + /// Number of slots managed by this container. + static const size_t HISTORY_RING_SIZE = get_allocator_ring_size_gt_min( + RING_MAX_HISTORY_SIZE + get_max_slot_ul_alloc_delay(NTN_CELL_SPECIFIC_KOFFSET_MAX)); sched_decision_history.resize(HISTORY_RING_SIZE); } From d8d64b2da95f4e1c82887859f7168dd408ebe104 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Tue, 17 Sep 2024 16:37:42 +0200 Subject: [PATCH 070/174] du_high: use NTN cell specific K offset from configuration --- lib/du/du_high/adapters/mac_test_mode_adapter.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp index fe30fb626f..08865c2efb 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp @@ -91,13 +91,12 @@ mac_test_mode_cell_adapter::mac_test_mode_cell_adapter( logger(srslog::fetch_basic_logger("MAC")), ue_info_mgr(ue_info_mgr_) { - /// \brief Number of previous slot results to keep in history before they get deleted. - /// - /// Having access to past decisions is useful during the handling of error indications. + // Number of previous slot results to keep in history before they get deleted. Having access to past decisions is + // useful during the handling of error indications. static const size_t RING_MAX_HISTORY_SIZE = 8; - /// Number of slots managed by this container. + // Number of slots managed by this container. static const size_t HISTORY_RING_SIZE = get_allocator_ring_size_gt_min( - RING_MAX_HISTORY_SIZE + get_max_slot_ul_alloc_delay(NTN_CELL_SPECIFIC_KOFFSET_MAX)); + RING_MAX_HISTORY_SIZE + get_max_slot_ul_alloc_delay(cell_cfg.sched_req.ntn_cs_koffset)); sched_decision_history.resize(HISTORY_RING_SIZE); } From 4870345fed66475fd7c79fc78807725d1994caa3 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 2 Sep 2024 18:07:42 +0200 Subject: [PATCH 071/174] mac: add mutexes in test mode to detect overflows in ring storage --- .../adapters/mac_test_mode_adapter.cpp | 294 ++++++++++-------- .../du_high/adapters/mac_test_mode_adapter.h | 12 +- 2 files changed, 174 insertions(+), 132 deletions(-) diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp index 08865c2efb..b48164b490 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp @@ -71,6 +71,13 @@ class test_ue_mac_sdu_tx_builder_adapter : public mac_sdu_tx_builder byte_buffer tx_sdu; }; +size_t get_ring_size(const mac_cell_creation_request& cell_cfg) +{ + // Note: The history ring size has to be a multiple of the TDD frame size in slots. + // Number of slots managed by this container. + return get_allocator_ring_size_gt_min(get_max_slot_ul_alloc_delay(cell_cfg.sched_req.ntn_cs_koffset)); +} + } // namespace mac_test_mode_cell_adapter::mac_test_mode_cell_adapter( @@ -89,75 +96,83 @@ mac_test_mode_cell_adapter::mac_test_mode_cell_adapter( result_notifier(result_notifier_), dl_bs_notifier(std::move(dl_bs_notifier_)), logger(srslog::fetch_basic_logger("MAC")), + sched_decision_history(get_ring_size(cell_cfg)), ue_info_mgr(ue_info_mgr_) { - // Number of previous slot results to keep in history before they get deleted. Having access to past decisions is - // useful during the handling of error indications. - static const size_t RING_MAX_HISTORY_SIZE = 8; - // Number of slots managed by this container. - static const size_t HISTORY_RING_SIZE = get_allocator_ring_size_gt_min( - RING_MAX_HISTORY_SIZE + get_max_slot_ul_alloc_delay(cell_cfg.sched_req.ntn_cs_koffset)); - sched_decision_history.resize(HISTORY_RING_SIZE); } void mac_test_mode_cell_adapter::handle_slot_indication(slot_point sl_tx) { if (test_ue_cfg.auto_ack_indication_delay.has_value()) { // auto-generation of CRC/UCI indication is enabled. - slot_point sl_rx = sl_tx - test_ue_cfg.auto_ack_indication_delay.value(); - const slot_descision_history& entry = sched_decision_history[sl_rx.to_uint() % sched_decision_history.size()]; + slot_point sl_rx = sl_tx - test_ue_cfg.auto_ack_indication_delay.value(); + const slot_decision_history& entry = sched_decision_history[get_ring_idx(sl_rx)]; + std::unique_lock lock(entry.mutex); + if (entry.slot == sl_rx) { + // Handle auto-generation of pending CRC indications. + if (not entry.puschs.empty()) { + mac_crc_indication_message crc_ind{}; + crc_ind.sl_rx = sl_rx; - // Handle auto-generation of pending CRC indications. - if (not entry.puschs.empty()) { - mac_crc_indication_message crc_ind{}; - crc_ind.sl_rx = sl_rx; + for (const ul_sched_info& pusch : entry.puschs) { + auto& crc_pdu = crc_ind.crcs.emplace_back(); + crc_pdu.rnti = pusch.pusch_cfg.rnti; + crc_pdu.harq_id = pusch.pusch_cfg.harq_id; + // Force CRC=OK for test UE. + crc_pdu.tb_crc_success = true; + // Force UL SINR. + crc_pdu.ul_sinr_dB = 100; + } - for (const ul_sched_info& pusch : entry.puschs) { - auto& crc_pdu = crc_ind.crcs.emplace_back(); - crc_pdu.rnti = pusch.pusch_cfg.rnti; - crc_pdu.harq_id = pusch.pusch_cfg.harq_id; - // Force CRC=OK for test UE. - crc_pdu.tb_crc_success = true; - // Force UL SINR. - crc_pdu.ul_sinr_dB = 100; - } + // Unlock before forward CRC indication + lock.unlock(); - // Forward CRC to the real MAC. - forward_crc_ind_to_mac(crc_ind); - } + // Forward CRC to the real MAC. + forward_crc_ind_to_mac(crc_ind); - // Handle auto-generation of pending UCI indications. - mac_uci_indication_message uci_ind; - uci_ind.sl_rx = sl_rx; - - // > Handle pending PUCCHs. - for (const pucch_info& pucch : entry.pucchs) { - mac_uci_pdu& pdu = uci_ind.ucis.emplace_back(); - pdu.rnti = pucch.crnti; - switch (pucch.format) { - case pucch_format::FORMAT_0: - case pucch_format::FORMAT_1: { - fill_uci_pdu(pdu.pdu.emplace(), pucch); - } break; - case pucch_format::FORMAT_2: { - fill_uci_pdu(pdu.pdu.emplace(), pucch); - } break; - default: - break; + lock.lock(); } - } - // > Handle pending PUSCHs. - for (const ul_sched_info& pusch : entry.puschs) { - if (pusch.uci.has_value()) { + // Handle auto-generation of pending UCI indications. + mac_uci_indication_message uci_ind; + uci_ind.sl_rx = sl_rx; + + // > Handle pending PUCCHs. + for (const pucch_info& pucch : entry.pucchs) { mac_uci_pdu& pdu = uci_ind.ucis.emplace_back(); - pdu.rnti = pusch.pusch_cfg.rnti; - fill_uci_pdu(pdu.pdu.emplace(), pusch); + pdu.rnti = pucch.crnti; + switch (pucch.format) { + case pucch_format::FORMAT_0: + case pucch_format::FORMAT_1: { + fill_uci_pdu(pdu.pdu.emplace(), pucch); + } break; + case pucch_format::FORMAT_2: { + fill_uci_pdu(pdu.pdu.emplace(), pucch); + } break; + default: + break; + } } - } - // Forward UCI indication to real MAC. - forward_uci_ind_to_mac(uci_ind); + // > Handle pending PUSCHs. + for (const ul_sched_info& pusch : entry.puschs) { + if (pusch.uci.has_value()) { + mac_uci_pdu& pdu = uci_ind.ucis.emplace_back(); + pdu.rnti = pusch.pusch_cfg.rnti; + fill_uci_pdu(pdu.pdu.emplace(), pusch); + } + } + + // Unlock before forward UCI indication + lock.unlock(); + + // Forward UCI indication to real MAC. + forward_uci_ind_to_mac(uci_ind); + } else { + logger.warning( + "Failed to generate UCI and CRC for slot={}. Cause: Overflow of the test mode internal storage detected", + sl_rx); + } } slot_handler.handle_slot_indication(sl_tx); @@ -165,12 +180,16 @@ void mac_test_mode_cell_adapter::handle_slot_indication(slot_point sl_tx) void mac_test_mode_cell_adapter::handle_error_indication(slot_point sl_tx, error_event event) { - slot_descision_history& entry = sched_decision_history[sl_tx.to_uint() % sched_decision_history.size()]; - if (event.pusch_and_pucch_discarded) { - // Delete expected UCI and CRC indications that resulted from the scheduler decisions for this slot. - entry.puschs.clear(); - entry.pucchs.clear(); + slot_decision_history& entry = sched_decision_history[get_ring_idx(sl_tx)]; + std::lock_guard lock(entry.mutex); + if (entry.slot == sl_tx) { + // Delete expected UCI and CRC indications that resulted from the scheduler decisions for this slot. + entry.puschs.clear(); + entry.pucchs.clear(); + } else { + logger.warning("Failed to handle error indication. Cause: Overflow of the test mode internal storage detected"); + } } slot_handler.handle_error_indication(sl_tx, event); @@ -178,33 +197,40 @@ void mac_test_mode_cell_adapter::handle_error_indication(slot_point sl_tx, error void mac_test_mode_cell_adapter::handle_crc(const mac_crc_indication_message& msg) { - // Forward CRC to MAC, but remove the UCI for the test mode UE. - mac_crc_indication_message msg_copy; - msg_copy.sl_rx = msg.sl_rx; - for (const mac_crc_pdu& crc : msg.crcs) { - if (ue_info_mgr.is_test_ue(crc.rnti)) { - // test mode UE case. - - // Find respective PUSCH PDU that was previously scheduled. - const slot_descision_history& entry = sched_decision_history[msg.sl_rx.to_uint() % sched_decision_history.size()]; - bool found = std::any_of(entry.puschs.begin(), entry.puschs.end(), [&](const ul_sched_info& pusch) { - return pusch.pusch_cfg.rnti == crc.rnti and pusch.pusch_cfg.harq_id == crc.harq_id; - }); - if (not found) { - logger.warning( - "c-rnti={}: Mismatch between provided CRC and expected PUSCH for slot_rx={}", crc.rnti, msg.sl_rx); - continue; - } + mac_crc_indication_message msg_copy = msg; - // Intercept the CRC indication and force crc=OK and UL SNR. - mac_crc_pdu test_crc = crc; - test_crc.tb_crc_success = true; - test_crc.ul_sinr_dB = 100; - msg_copy.crcs.push_back(test_crc); + { + // Try to acquire history. + const slot_decision_history& entry = sched_decision_history[get_ring_idx(msg.sl_rx)]; + std::lock_guard lock(entry.mutex); + if (entry.slot == msg.sl_rx) { + // Forward CRC to MAC, but remove the UCI for the test mode UE. + for (mac_crc_pdu& crc : msg_copy.crcs) { + if (ue_info_mgr.is_test_ue(crc.rnti)) { + // test mode UE case. + + // Find respective PUSCH PDU that was previously scheduled. + bool found = std::any_of(entry.puschs.begin(), entry.puschs.end(), [&](const ul_sched_info& pusch) { + return pusch.pusch_cfg.rnti == crc.rnti and pusch.pusch_cfg.harq_id == crc.harq_id; + }); + if (not found) { + logger.warning( + "c-rnti={}: Failed to set CRC. Cause: Mismatch between provided CRC and expected PUSCH for slot_rx={}", + crc.rnti, + msg.sl_rx); + continue; + } + // Intercept the CRC indication and force crc=OK and UL SNR. + crc.tb_crc_success = true; + crc.ul_sinr_dB = 100; + } + } } else { - // non-test mode UE. Forward the original CRC PDU. - msg_copy.crcs.push_back(crc); + // Failed to lock entry in ring. + logger.warning( + "Unable to force CRC test mode value for slot={}. Cause: Overflow detected in test mode internal storage", + msg.sl_rx); } } @@ -395,48 +421,51 @@ void mac_test_mode_cell_adapter::forward_crc_ind_to_mac(const mac_crc_indication void mac_test_mode_cell_adapter::handle_uci(const mac_uci_indication_message& msg) { - const slot_descision_history& entry = sched_decision_history[msg.sl_rx.to_uint() % sched_decision_history.size()]; + mac_uci_indication_message msg_copy{msg}; + const slot_decision_history& entry = sched_decision_history[get_ring_idx(msg.sl_rx)]; - // Forward UCI to MAC, but alter the UCI for the test mode UE. - mac_uci_indication_message msg_copy; - msg_copy.sl_rx = msg.sl_rx; - for (const mac_uci_pdu& pdu : msg.ucis) { - if (not ue_info_mgr.is_test_ue(pdu.rnti)) { - // non-test mode UE. Forward the original UCI indication PDU. - msg_copy.ucis.push_back(pdu); - } else { - // test mode UE. - // Intercept the UCI indication and force HARQ-ACK=ACK and CSI. - msg_copy.ucis.push_back(pdu); - mac_uci_pdu& test_uci = msg_copy.ucis.back(); - - bool entry_found = false; - if (std::holds_alternative(test_uci.pdu)) { - for (const ul_sched_info& pusch : entry.puschs) { - if (pusch.pusch_cfg.rnti == pdu.rnti and pusch.uci.has_value()) { - fill_uci_pdu(std::get(test_uci.pdu), pusch); - entry_found = true; - } - } - } else { - // PUCCH case. - for (const pucch_info& pucch : entry.pucchs) { - if (pucch_info_and_uci_ind_match(pucch, test_uci)) { - // Intercept the UCI indication and force HARQ-ACK=ACK and UCI. - if (pucch.format == pucch_format::FORMAT_0 or pucch.format == pucch_format::FORMAT_1) { - fill_uci_pdu(std::get(test_uci.pdu), pucch); - } else { - fill_uci_pdu(std::get(test_uci.pdu), pucch); + { + std::unique_lock lock(entry.mutex); + if (entry.slot == msg_copy.sl_rx) { + // Forward UCI to MAC, but alter the UCI for the test mode UE. + for (mac_uci_pdu& test_uci : msg_copy.ucis) { + if (ue_info_mgr.is_test_ue(test_uci.rnti)) { + bool entry_found = false; + if (std::holds_alternative(test_uci.pdu)) { + for (const ul_sched_info& pusch : entry.puschs) { + if (pusch.pusch_cfg.rnti == test_uci.rnti and pusch.uci.has_value()) { + fill_uci_pdu(std::get(test_uci.pdu), pusch); + entry_found = true; + } + } + } else { + // PUCCH case. + for (const pucch_info& pucch : entry.pucchs) { + if (pucch_info_and_uci_ind_match(pucch, test_uci)) { + // Intercept the UCI indication and force HARQ-ACK=ACK and UCI. + if (pucch.format == pucch_format::FORMAT_0 or pucch.format == pucch_format::FORMAT_1) { + fill_uci_pdu(std::get(test_uci.pdu), pucch); + } else { + fill_uci_pdu(std::get(test_uci.pdu), pucch); + } + entry_found = true; + } } - entry_found = true; } - } - } - if (not entry_found) { - msg_copy.ucis.pop_back(); - logger.warning("c-rnti={}: Mismatch between provided UCI and expected UCI for slot_rx={}", pdu.rnti, msg.sl_rx); + if (not entry_found) { + logger.warning("c-rnti={}: Failed to set UCI test mode value. Cause: Mismatch between provided UCI and " + "expected UCI for slot_rx={}", + test_uci.rnti, + msg.sl_rx); + } + } } + } else { + // Failed to lock entry in history ring. + logger.warning( + "Unable to set UCI test mode value for slot={}. Cause: Overflow detected in test mode internal storage", + msg.sl_rx); } } @@ -447,24 +476,29 @@ void mac_test_mode_cell_adapter::handle_uci(const mac_uci_indication_message& ms // Intercepts the UL results coming from the MAC. void mac_test_mode_cell_adapter::on_new_uplink_scheduler_results(const mac_ul_sched_result& ul_res) { - slot_descision_history& entry = sched_decision_history[ul_res.slot.to_uint() % sched_decision_history.size()]; + { + slot_decision_history& entry = sched_decision_history[get_ring_idx(ul_res.slot)]; + std::unique_lock lock(entry.mutex); + entry.slot = ul_res.slot; - // Resets the history for this ring element. - entry.pucchs.clear(); - entry.puschs.clear(); + // Resets the history for this ring element. + entry.pucchs.clear(); + entry.puschs.clear(); - // Fill the ring element with the scheduler decisions. - for (const pucch_info& pucch : ul_res.ul_res->pucchs) { - if (ue_info_mgr.is_test_ue(pucch.crnti)) { - entry.pucchs.push_back(pucch); + // Fill the ring element with the scheduler decisions. + for (const pucch_info& pucch : ul_res.ul_res->pucchs) { + if (ue_info_mgr.is_test_ue(pucch.crnti)) { + entry.pucchs.push_back(pucch); + } } - } - for (const ul_sched_info& pusch : ul_res.ul_res->puschs) { - if (ue_info_mgr.is_test_ue(pusch.pusch_cfg.rnti)) { - entry.puschs.push_back(pusch); + for (const ul_sched_info& pusch : ul_res.ul_res->puschs) { + if (ue_info_mgr.is_test_ue(pusch.pusch_cfg.rnti)) { + entry.puschs.push_back(pusch); + } } } + // Forward results to PHY. result_notifier.on_new_uplink_scheduler_results(ul_res); } diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.h b/lib/du/du_high/adapters/mac_test_mode_adapter.h index 63a54b3bb2..8f04f360fe 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.h +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.h @@ -14,6 +14,7 @@ #include "srsran/mac/mac.h" #include "srsran/mac/mac_cell_result.h" #include "srsran/srslog/srslog.h" +#include #include namespace srsran { @@ -154,7 +155,12 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler, void handle_uci(const mac_uci_indication_message& msg) override; private: - struct slot_descision_history { + struct slot_decision_history { + // Locks a given slot. + // Note: In normal scenarios, this mutex will have no contention, as the times of write and read are separate. + // However, if the ring buffer is too small, this may stop being true. + mutable std::mutex mutex; + slot_point slot; std::vector pucchs; std::vector puschs; }; @@ -166,6 +172,8 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler, void forward_uci_ind_to_mac(const mac_uci_indication_message& uci_msg); void forward_crc_ind_to_mac(const mac_crc_indication_message& crc_msg); + size_t get_ring_idx(slot_point sl) const { return sl.to_uint() % sched_decision_history.size(); } + const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg; mac_cell_control_information_handler& adapted; mac_pdu_handler& pdu_handler; @@ -174,7 +182,7 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler, std::function dl_bs_notifier; srslog::basic_logger& logger; - std::vector sched_decision_history; + std::vector sched_decision_history; test_ue_info_manager& ue_info_mgr; }; From bfe53df20d88bab27cc226aef17f3c076824c522 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 17 Sep 2024 21:41:45 +0200 Subject: [PATCH 072/174] mac: fix failing tests in test mode --- .../adapters/mac_test_mode_adapter.cpp | 65 +++++---- .../du_high/mac_test_mode_adapter_test.cpp | 126 +++++++++++++++--- 2 files changed, 146 insertions(+), 45 deletions(-) diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp index b48164b490..de52d83d8e 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp @@ -169,9 +169,9 @@ void mac_test_mode_cell_adapter::handle_slot_indication(slot_point sl_tx) // Forward UCI indication to real MAC. forward_uci_ind_to_mac(uci_ind); } else { - logger.warning( - "Failed to generate UCI and CRC for slot={}. Cause: Overflow of the test mode internal storage detected", - sl_rx); + logger.warning("TEST_MODE: Failed to generate UCI and CRC for slot={}. Cause: Overflow of the test mode internal " + "storage detected", + sl_rx); } } @@ -188,7 +188,9 @@ void mac_test_mode_cell_adapter::handle_error_indication(slot_point sl_tx, error entry.puschs.clear(); entry.pucchs.clear(); } else { - logger.warning("Failed to handle error indication. Cause: Overflow of the test mode internal storage detected"); + logger.warning("TEST_MODE: Failed to handle error indication for slot={}. Cause: Overflow of the test mode " + "internal storage detected", + sl_tx); } } @@ -199,8 +201,8 @@ void mac_test_mode_cell_adapter::handle_crc(const mac_crc_indication_message& ms { mac_crc_indication_message msg_copy = msg; - { - // Try to acquire history. + if (not test_ue_cfg.auto_ack_indication_delay.has_value()) { + // Acquire history. const slot_decision_history& entry = sched_decision_history[get_ring_idx(msg.sl_rx)]; std::lock_guard lock(entry.mutex); if (entry.slot == msg.sl_rx) { @@ -214,10 +216,10 @@ void mac_test_mode_cell_adapter::handle_crc(const mac_crc_indication_message& ms return pusch.pusch_cfg.rnti == crc.rnti and pusch.pusch_cfg.harq_id == crc.harq_id; }); if (not found) { - logger.warning( - "c-rnti={}: Failed to set CRC. Cause: Mismatch between provided CRC and expected PUSCH for slot_rx={}", - crc.rnti, - msg.sl_rx); + logger.warning("TEST_MODE c-rnti={}: Failed to set CRC value for slot={}. Cause: Mismatch between provided " + "CRC and expected PUSCH", + crc.rnti, + msg.sl_rx); continue; } @@ -228,10 +230,16 @@ void mac_test_mode_cell_adapter::handle_crc(const mac_crc_indication_message& ms } } else { // Failed to lock entry in ring. - logger.warning( - "Unable to force CRC test mode value for slot={}. Cause: Overflow detected in test mode internal storage", - msg.sl_rx); + logger.warning("TEST_MODE: Unable to set CRC value for slot={}. Cause: Overflow detected in test " + "mode internal storage", + msg.sl_rx); } + } else { + // In case of auto-ACK mode, test mode UEs are removed from CRC. + msg_copy.crcs.erase(std::remove_if(msg_copy.crcs.begin(), + msg_copy.crcs.end(), + [this](const auto& crc) { return ue_info_mgr.is_test_ue(crc.rnti); }), + msg_copy.crcs.end()); } // Forward resulting CRC indication to real MAC. @@ -379,7 +387,7 @@ void mac_test_mode_cell_adapter::forward_uci_ind_to_mac(const mac_uci_indication if (test_ue_cfg.pusch_active) { auto rx_pdu = create_test_pdu_with_bsr(uci_msg.sl_rx, pdu.rnti, to_harq_id(0)); if (not rx_pdu.has_value()) { - logger.warning("Unable to create test PDU with BSR"); + logger.warning("TEST_MODE c-rnti={}: Unable to create test PDU with BSR", pdu.rnti); continue; } // In case of PUSCH test mode is enabled, push a BSR to trigger the first PUSCH. @@ -411,7 +419,7 @@ void mac_test_mode_cell_adapter::forward_crc_ind_to_mac(const mac_crc_indication auto rx_pdu = create_test_pdu_with_bsr(crc_msg.sl_rx, pdu.rnti, to_harq_id(pdu.harq_id)); if (not rx_pdu.has_value()) { - logger.warning("Unable to create test PDU with BSR"); + logger.warning("TEST_MODE c-rnti={}: Unable to create test PDU with BSR", pdu.rnti); continue; } // In case of test mode UE, auto-forward a positive BSR. @@ -421,10 +429,10 @@ void mac_test_mode_cell_adapter::forward_crc_ind_to_mac(const mac_crc_indication void mac_test_mode_cell_adapter::handle_uci(const mac_uci_indication_message& msg) { - mac_uci_indication_message msg_copy{msg}; - const slot_decision_history& entry = sched_decision_history[get_ring_idx(msg.sl_rx)]; + mac_uci_indication_message msg_copy{msg}; - { + if (not test_ue_cfg.auto_ack_indication_delay.has_value()) { + const slot_decision_history& entry = sched_decision_history[get_ring_idx(msg.sl_rx)]; std::unique_lock lock(entry.mutex); if (entry.slot == msg_copy.sl_rx) { // Forward UCI to MAC, but alter the UCI for the test mode UE. @@ -454,19 +462,26 @@ void mac_test_mode_cell_adapter::handle_uci(const mac_uci_indication_message& ms } if (not entry_found) { - logger.warning("c-rnti={}: Failed to set UCI test mode value. Cause: Mismatch between provided UCI and " - "expected UCI for slot_rx={}", - test_uci.rnti, - msg.sl_rx); + logger.warning( + "TEST_MODE c-rnti={}: Failed to set UCI value for slot={}. Cause: Mismatch between provided UCI and " + "expected UCI", + test_uci.rnti, + msg.sl_rx); } } } } else { // Failed to lock entry in history ring. - logger.warning( - "Unable to set UCI test mode value for slot={}. Cause: Overflow detected in test mode internal storage", - msg.sl_rx); + logger.warning("TEST_MODE: Unable to set UCI value for slot={}. Cause: Overflow detected in test mode " + "internal storage", + msg.sl_rx); } + } else { + // In case of auto-ACK mode, test mode UEs are removed from UCI. + msg_copy.ucis.erase(std::remove_if(msg_copy.ucis.begin(), + msg_copy.ucis.end(), + [this](const auto& u) { return ue_info_mgr.is_test_ue(u.rnti); }), + msg_copy.ucis.end()); } // Forward UCI indication to real MAC. diff --git a/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp b/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp index ab54ab93c3..88a62c918a 100644 --- a/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp +++ b/tests/integrationtests/du_high/mac_test_mode_adapter_test.cpp @@ -122,10 +122,27 @@ void PrintTo(const test_params& value, ::std::ostream* os) } } -class mac_test_mode_adapter_test : public ::testing::TestWithParam +static mac_uci_pdu make_random_uci_with_csi(rnti_t test_rnti = to_rnti(0x4601)) +{ + mac_uci_pdu pdu; + pdu.rnti = test_rnti; + + mac_uci_pdu::pucch_f2_or_f3_or_f4_type f2; + f2.csi_part1_info.emplace(); + f2.csi_part1_info->is_valid = false; + f2.csi_part1_info->payload.resize(test_rgen::uniform_int(0, 11)); + for (unsigned i = 0; i != f2.csi_part1_info->payload.size(); ++i) { + f2.csi_part1_info->payload.set(i, test_rgen::uniform_int(0, 1)); + } + + pdu.pdu = f2; + return pdu; +} + +class base_mac_test_mode_test { protected: - mac_test_mode_adapter_test() : params(GetParam()), adapter{params.test_ue_cfg, phy} + base_mac_test_mode_test(const test_params& params_) : params(params_), adapter{params.test_ue_cfg, phy} { adapter.connect(std::make_unique(mac_events, adapter.get_phy_notifier())); @@ -163,24 +180,93 @@ class mac_test_mode_adapter_test : public ::testing::TestWithParam slot_point next_slot{0, 0}; }; -mac_uci_pdu make_random_uci_with_csi(rnti_t test_rnti = to_rnti(0x4601)) +class mac_test_mode_test : public base_mac_test_mode_test, public ::testing::Test { - mac_uci_pdu pdu; - pdu.rnti = test_rnti; +protected: + mac_test_mode_test() : base_mac_test_mode_test(test_params{1, {to_rnti(0x4444), 1, std::nullopt, true, true, 12}}) {} +}; - mac_uci_pdu::pucch_f2_or_f3_or_f4_type f2; - f2.csi_part1_info.emplace(); - f2.csi_part1_info->is_valid = false; - f2.csi_part1_info->payload.resize(test_rgen::uniform_int(0, 11)); - for (unsigned i = 0; i != f2.csi_part1_info->payload.size(); ++i) { - f2.csi_part1_info->payload.set(i, test_rgen::uniform_int(0, 1)); - } +TEST_F(mac_test_mode_test, when_test_mode_ue_has_pucch_grants_then_uci_indications_are_auto_forwarded_to_mac) +{ + // PUCCH got scheduled for test mode UE. + ul_sched_result ul_res{}; + pucch_info& pucch = ul_res.pucchs.emplace_back(); + pucch.crnti = this->params.test_ue_cfg.rnti; + pucch.format = srsran::pucch_format::FORMAT_1; + pucch.format_1.harq_ack_nof_bits = 1; + pucch.format_1.sr_bits = sr_nof_bits::no_sr; + mac_events.next_ul_sched_res.emplace(); + mac_events.next_ul_sched_res->slot = next_slot; + mac_events.next_ul_sched_res->ul_res = &ul_res; - pdu.pdu = f2; - return pdu; + // Run the slot with PUCCH scheduled. + slot_point sl_rx = next_slot; + this->run_slot(); + + // Forward UCI indication. + mac_uci_indication_message uci; + uci.sl_rx = sl_rx; + mac_uci_pdu& pdu = uci.ucis.emplace_back(); + pdu.rnti = this->params.test_ue_cfg.rnti; + mac_uci_pdu::pucch_f0_or_f1_type& f1_uci = pdu.pdu.emplace(); + f1_uci.harq_info.emplace(); + f1_uci.harq_info->harqs.resize(1); + f1_uci.harq_info->harqs[0] = uci_pucch_f0_or_f1_harq_values::nack; + this->adapter.get_control_info_handler(to_du_cell_index(0)).handle_uci(uci); + + ASSERT_TRUE(mac_events.last_uci.has_value()); + ASSERT_EQ(mac_events.last_uci->sl_rx, sl_rx); + ASSERT_EQ(mac_events.last_uci->ucis.size(), 1); + ASSERT_EQ(mac_events.last_uci->ucis[0].rnti, this->params.test_ue_cfg.rnti); + ASSERT_TRUE(std::holds_alternative(mac_events.last_uci->ucis[0].pdu)); + const auto& f1 = std::get(mac_events.last_uci->ucis[0].pdu); + ASSERT_FALSE(f1.sr_info.has_value()); + ASSERT_TRUE(f1.harq_info.has_value()); + ASSERT_EQ(f1.harq_info->harqs.size(), 1); + ASSERT_EQ(f1.harq_info->harqs[0], uci_pucch_f0_or_f1_harq_values::ack); + ASSERT_TRUE(f1.ul_sinr_dB.value() > 0); +} + +TEST_F(mac_test_mode_test, when_test_mode_ue_has_pusch_grants_then_crc_indications_are_auto_forwarded_to_mac) +{ + // PUCCH got scheduled for test mode UE. + ul_sched_result ul_res{}; + ul_sched_info& ulgrant = ul_res.puschs.emplace_back(); + ulgrant.pusch_cfg.rnti = this->params.test_ue_cfg.rnti; + ulgrant.pusch_cfg.harq_id = to_harq_id(test_rgen::uniform_int(0, 15)); + mac_events.next_ul_sched_res.emplace(); + mac_events.next_ul_sched_res->slot = next_slot; + mac_events.next_ul_sched_res->ul_res = &ul_res; + + // Run the slot with PUSCH scheduled. + slot_point sl_rx = next_slot; + this->run_slot(); + + // Forward CRC indication. + mac_crc_indication_message crc; + crc.sl_rx = sl_rx; + mac_crc_pdu& pdu = crc.crcs.emplace_back(); + pdu.rnti = this->params.test_ue_cfg.rnti; + pdu.harq_id = ulgrant.pusch_cfg.harq_id; + pdu.tb_crc_success = false; + this->adapter.get_control_info_handler(to_du_cell_index(0)).handle_crc(crc); + + ASSERT_TRUE(mac_events.last_crc.has_value()); + ASSERT_EQ(mac_events.last_crc->sl_rx, sl_rx); + ASSERT_EQ(mac_events.last_crc->crcs.size(), 1); + ASSERT_EQ(mac_events.last_crc->crcs[0].rnti, this->params.test_ue_cfg.rnti); + ASSERT_EQ(mac_events.last_crc->crcs[0].harq_id, ulgrant.pusch_cfg.harq_id); + ASSERT_TRUE(mac_events.last_crc->crcs[0].tb_crc_success); + ASSERT_TRUE(mac_events.last_crc->crcs[0].ul_sinr_dB.value() > 0); } -TEST_P(mac_test_mode_adapter_test, when_uci_is_only_for_test_mode_ue_then_it_is_ignored) +class mac_test_mode_auto_uci_test : public base_mac_test_mode_test, public ::testing::TestWithParam +{ +protected: + mac_test_mode_auto_uci_test() : base_mac_test_mode_test(GetParam()) {} +}; + +TEST_P(mac_test_mode_auto_uci_test, when_uci_is_only_for_test_mode_ue_then_it_is_ignored) { mac_uci_indication_message uci_ind; uci_ind.sl_rx = {0, 0}; @@ -190,7 +276,7 @@ TEST_P(mac_test_mode_adapter_test, when_uci_is_only_for_test_mode_ue_then_it_is_ ASSERT_FALSE(mac_events.last_uci.has_value()); } -TEST_P(mac_test_mode_adapter_test, when_uci_is_also_for_other_ues_then_test_mode_ue_is_cropped) +TEST_P(mac_test_mode_auto_uci_test, when_uci_is_also_for_other_ues_then_test_mode_ue_is_cropped) { mac_uci_indication_message uci_ind; uci_ind.sl_rx = {0, 0}; @@ -204,7 +290,7 @@ TEST_P(mac_test_mode_adapter_test, when_uci_is_also_for_other_ues_then_test_mode ASSERT_EQ(mac_events.last_uci->ucis[0].rnti, to_rnti(0x4602)); } -TEST_P(mac_test_mode_adapter_test, when_test_mode_ue_has_pucch_grants_then_uci_indications_are_auto_forwarded_to_mac) +TEST_P(mac_test_mode_auto_uci_test, when_test_mode_ue_has_pucch_grants_then_uci_indications_are_auto_forwarded_to_mac) { // PUCCH got scheduled for test mode UE. ul_sched_result ul_res{}; @@ -242,7 +328,7 @@ TEST_P(mac_test_mode_adapter_test, when_test_mode_ue_has_pucch_grants_then_uci_i ASSERT_TRUE(f1.ul_sinr_dB.value() > 0); } -TEST_P(mac_test_mode_adapter_test, when_test_mode_ue_has_pusch_grants_then_crc_indications_are_auto_forwarded_to_mac) +TEST_P(mac_test_mode_auto_uci_test, when_test_mode_ue_has_pusch_grants_then_crc_indications_are_auto_forwarded_to_mac) { // PUCCH got scheduled for test mode UE. ul_sched_result ul_res{}; @@ -274,7 +360,7 @@ TEST_P(mac_test_mode_adapter_test, when_test_mode_ue_has_pusch_grants_then_crc_i ASSERT_TRUE(mac_events.last_crc->crcs[0].ul_sinr_dB.value() > 0); } -TEST_P(mac_test_mode_adapter_test, when_uci_is_forwarded_to_mac_then_test_mode_csi_params_are_enforced) +TEST_P(mac_test_mode_auto_uci_test, when_uci_is_forwarded_to_mac_then_test_mode_csi_params_are_enforced) { // PUCCH got scheduled for test mode UE. ul_sched_result ul_res{}; @@ -352,7 +438,7 @@ TEST_P(mac_test_mode_adapter_test, when_uci_is_forwarded_to_mac_then_test_mode_c } INSTANTIATE_TEST_SUITE_P(test_configs, - mac_test_mode_adapter_test, + mac_test_mode_auto_uci_test, // clang-format off ::testing::Values( // ports rnti nof_ues CQI RI PMI i1_1 i1_3 i2 From 76f520bdb30d853efc5c52667ca1d0c9c486f55f Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Tue, 3 Sep 2024 16:54:12 +0530 Subject: [PATCH 073/174] sched: fix computing of slice priorities to support UL heavy TDD scenario --- lib/scheduler/slicing/slice_scheduler.cpp | 52 +++++++++++++------ lib/scheduler/slicing/slice_scheduler.h | 10 +++- .../slicing/slice_scheduler_test.cpp | 6 +-- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/lib/scheduler/slicing/slice_scheduler.cpp b/lib/scheduler/slicing/slice_scheduler.cpp index 7af3c6c1fd..541dfd4619 100644 --- a/lib/scheduler/slicing/slice_scheduler.cpp +++ b/lib/scheduler/slicing/slice_scheduler.cpp @@ -16,7 +16,10 @@ using namespace srsran; slice_scheduler::slice_scheduler(const cell_configuration& cell_cfg_, ue_repository& ues_) : - cell_cfg(cell_cfg_), logger(srslog::fetch_basic_logger("SCHED")), ues(ues_) + cell_cfg(cell_cfg_), + logger(srslog::fetch_basic_logger("SCHED")), + current_slot(to_numerology_value(cell_cfg.dl_cfg_common.init_dl_bwp.generic_params.scs), 0), + ues(ues_) { // Create a number of slices equal to the number of configured RRM Policy members + 1 (default SRB slice) + 1 (default // DRB slice). @@ -58,6 +61,8 @@ slice_scheduler::slice_scheduler(const cell_configuration& cell_cfg_, ue_reposit void slice_scheduler::slot_indication(slot_point slot_tx) { + current_slot = slot_tx; + slot_count++; // Update the context of each slice. @@ -72,8 +77,10 @@ void slice_scheduler::slot_indication(slot_point slot_tx) unsigned max_rbs = slice.inst.pdsch_rb_count <= slice.inst.cfg.min_prb and slice.inst.cfg.min_prb > 0 ? slice.inst.cfg.min_prb : slice.inst.cfg.max_prb; - dl_prio_queue.push(slice_candidate_context{ - slice.inst.id, slice.get_prio(true, slot_count, slot_tx), {slice.inst.pdsch_rb_count, max_rbs}, slot_tx}); + dl_prio_queue.push(slice_candidate_context{slice.inst.id, + slice.get_prio(true, slot_count, slot_tx, slot_tx, slices.size(), false), + {slice.inst.pdsch_rb_count, max_rbs}, + slot_tx}); // TODO: Revisit when PUSCH time domain resource list is also defined in UE dedicated configuration. span pusch_time_domain_list = @@ -85,10 +92,11 @@ void slice_scheduler::slot_indication(slot_point slot_tx) slice.inst.cfg.min_prb > 0 ? slice.inst.cfg.min_prb : slice.inst.cfg.max_prb; - ul_prio_queue.push(slice_candidate_context{slice.inst.id, - slice.get_prio(false, slot_count, pusch_slot), - {slice.inst.pusch_rb_count_per_slot[pusch_slot.to_uint()], max_rbs}, - pusch_slot}); + ul_prio_queue.push( + slice_candidate_context{slice.inst.id, + slice.get_prio(false, slot_count, slot_tx, pusch_slot, slices.size(), false), + {slice.inst.pusch_rb_count_per_slot[pusch_slot.to_uint()], max_rbs}, + pusch_slot}); } } } @@ -220,11 +228,11 @@ slice_scheduler::get_next_candidate() while (not prio_queue.empty()) { ran_slice_sched_context& chosen_slice = slices[prio_queue.top().id.value()]; interval rb_lims = prio_queue.top().rb_lims; - slot_point slot_tx = prio_queue.top().slot_tx; + slot_point pxsch_slot = prio_queue.top().slot_tx; prio_queue.pop(); unsigned rb_count = - IsDownlink ? chosen_slice.inst.pdsch_rb_count : chosen_slice.inst.pusch_rb_count_per_slot[slot_tx.to_uint()]; + IsDownlink ? chosen_slice.inst.pdsch_rb_count : chosen_slice.inst.pusch_rb_count_per_slot[pxsch_slot.to_uint()]; if (not rb_lims.contains(rb_count)) { // The slice has been scheduled in this slot with a number of RBs that is not within the limits for this // candidate. This could happen, for instance, if the scheduler could not schedule all RBs of a candidate @@ -238,9 +246,9 @@ slice_scheduler::get_next_candidate() rb_lims.stop() != cfg.max_prb) { // For the special case when minRB ratio>0, the first candidate for this slice was bounded between {RBLimsMin, // RBLimsMax}. We re-add the slice as a candidate, this time, with RB bounds {RBLimsMax, maxRB}. - priority_type prio = chosen_slice.get_prio(IsDownlink, slot_count, slot_tx); + priority_type prio = chosen_slice.get_prio(IsDownlink, slot_count, current_slot, pxsch_slot, slices.size(), true); unsigned min_rbs = rb_count > 0 ? rb_count : cfg.min_prb; - prio_queue.push(slice_candidate_context{chosen_slice.inst.id, prio, {min_rbs, cfg.max_prb}, slot_tx}); + prio_queue.push(slice_candidate_context{chosen_slice.inst.id, prio, {min_rbs, cfg.max_prb}, pxsch_slot}); } // Save current slot count. @@ -249,7 +257,7 @@ slice_scheduler::get_next_candidate() // Return the candidate. return std::conditional_t{ - chosen_slice.inst, slot_tx, rb_lims.stop()}; + chosen_slice.inst, pxsch_slot, rb_lims.stop()}; } return std::nullopt; } @@ -266,7 +274,10 @@ std::optional slice_scheduler::get_next_ul_candidate() slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_prio(bool is_dl, slot_count_type current_slot_count, - slot_point slot_tx) const + slot_point pdcch_slot, + slot_point pxsch_slot, + unsigned nof_slices, + bool slice_resched) const { // Note: The positive integer representing the priority of a slice consists of a concatenation of three priority // values: @@ -283,21 +294,28 @@ slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_pri static constexpr priority_type delay_bitsize = 8U; static constexpr priority_type rr_bitsize = 8U; - unsigned rb_count = is_dl ? inst.pdsch_rb_count : inst.pusch_rb_count_per_slot[slot_tx.to_uint()]; + unsigned rb_count = is_dl ? inst.pdsch_rb_count : inst.pusch_rb_count_per_slot[pxsch_slot.to_uint()]; if (not inst.active() or rb_count >= inst.cfg.max_prb) { // If the slice is not in a state to be scheduled in this slot, return skip priority level. return skip_prio; } // In case minRB > 0 and minimum RB ratio agreement is not yet reached, we give it a higher priority. - priority_type slice_prio = inst.cfg.min_prb > 0 and rb_count < inst.cfg.min_prb ? high_prio : default_prio; + priority_type slice_prio = + not slice_resched and inst.cfg.min_prb > 0 and rb_count < inst.cfg.min_prb ? high_prio : default_prio; // Increase priorities of slices that have not been scheduled for a long time. unsigned last_count = is_dl ? last_dl_slot : last_ul_slot; priority_type delay_prio = (current_slot_count - last_count) & ((1U << delay_bitsize) - 1U); // Round-robin across slices with the same slice and delay priorities. - priority_type rr_prio = (inst.id.value() % current_slot_count) & ((1U << rr_bitsize) - 1U); + priority_type rr_prio = (current_slot_count % nof_slices) == inst.id.value() ? 1 : 0; + rr_prio = rr_prio & ((1U << rr_bitsize) - 1U); + + // Give higher priority to slice with PxSCH slot closer to PDCCH slot. This is done to ensure that PxSCH does not get + // allocated too far in future such that no PxSCH can be allocated in the slots between current PDCCH slot and the + // slot at which PxSCH is allocated. + unsigned slot_diff = pxsch_slot - pdcch_slot; - return (slice_prio << (delay_bitsize + rr_bitsize)) + (delay_prio << rr_bitsize) + rr_prio; + return (slice_prio << (delay_bitsize + rr_bitsize)) + (delay_prio << rr_bitsize) + rr_prio - slot_diff; } diff --git a/lib/scheduler/slicing/slice_scheduler.h b/lib/scheduler/slicing/slice_scheduler.h index 8c545ab1e9..62b5e1ac63 100644 --- a/lib/scheduler/slicing/slice_scheduler.h +++ b/lib/scheduler/slicing/slice_scheduler.h @@ -66,7 +66,12 @@ class slice_scheduler } /// Determines the slice candidate priority. - priority_type get_prio(bool is_dl, slot_count_type current_slot_count, slot_point slot_tx) const; + priority_type get_prio(bool is_dl, + slot_count_type current_slot_count, + slot_point pdcch_slot, + slot_point pxsch_slot, + unsigned nof_slices, + bool slice_resched) const; }; struct slice_candidate_context { @@ -122,6 +127,9 @@ class slice_scheduler const cell_configuration& cell_cfg; srslog::basic_logger& logger; + // Represents current slot in the scheduler. This is updated on each slot indication. + slot_point current_slot; + ue_repository& ues; /// Vector circularly indexed by slot with the list of applicable PUSCH time domain resources per slot. diff --git a/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp b/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp index 7d317987bd..14787d2ffd 100644 --- a/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp +++ b/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp @@ -376,6 +376,7 @@ TEST_F(rb_ratio_slice_scheduler_test, ASSERT_EQ(next_dl_slice->id(), default_srb_slice_id); next_dl_slice = slice_sched.get_next_dl_candidate(); + ASSERT_EQ(next_dl_slice->id(), drb1_slice_id); next_dl_slice->store_grant(MIN_SLICE_RB); next_dl_slice = slice_sched.get_next_dl_candidate(); next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -383,14 +384,13 @@ TEST_F(rb_ratio_slice_scheduler_test, // New slot and priorities are reestablished. slice_sched.slot_indication(current_slot); - // Default SRB slice has very high priority. - next_dl_slice = slice_sched.get_next_dl_candidate(); - ASSERT_EQ(next_dl_slice->id(), default_srb_slice_id); next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_EQ(next_dl_slice->id(), drb1_slice_id); ASSERT_EQ(next_dl_slice->remaining_rbs(), MIN_SLICE_RB); next_dl_slice->store_grant(MIN_SLICE_RB); next_dl_slice = slice_sched.get_next_dl_candidate(); + ASSERT_EQ(next_dl_slice->id(), default_srb_slice_id); + next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_EQ(next_dl_slice->id(), drb1_slice_id); ASSERT_EQ(next_dl_slice->remaining_rbs(), MAX_SLICE_RB - MIN_SLICE_RB); next_dl_slice = slice_sched.get_next_dl_candidate(); From 64765fb97904b850a4164ed9947cd8c34f138f66 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Tue, 17 Sep 2024 16:25:16 +0200 Subject: [PATCH 074/174] unittest: add unittest for UL heavy TDD pattern --- .../scheduler/scheduler_tdd_test.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/unittests/scheduler/scheduler_tdd_test.cpp b/tests/unittests/scheduler/scheduler_tdd_test.cpp index 7a78585b03..f63bd943df 100644 --- a/tests/unittests/scheduler/scheduler_tdd_test.cpp +++ b/tests/unittests/scheduler/scheduler_tdd_test.cpp @@ -143,6 +143,19 @@ class scheduler_ul_tdd_tester : public base_scheduler_tdd_tester, public ::testi unsigned tdd_period = nof_slots_per_tdd_period(*cell_cfg_list[0].tdd_cfg_common); for (unsigned i = 0; i != 2 * tdd_period; ++i) { run_slot(); + + for (const ul_sched_info& pusch : this->last_sched_res_list[to_du_cell_index(0)]->ul.puschs) { + ul_crc_indication crc{}; + crc.cell_index = to_du_cell_index(0); + crc.sl_rx = this->last_result_slot(); + crc.crcs.resize(1); + crc.crcs[0].ue_index = ue_idx; + crc.crcs[0].rnti = ue_rnti; + crc.crcs[0].harq_id = to_harq_id(pusch.pusch_cfg.harq_id); + crc.crcs[0].tb_crc_success = true; + crc.crcs[0].ul_sinr_dB = 100.0F; + this->sched->handle_crc_indication(crc); + } } } }; @@ -208,6 +221,10 @@ INSTANTIATE_TEST_SUITE_P( tdd_test_params{true, {subcarrier_spacing::kHz30, {10, 7, 5, 2, 4}}}, // DDDDDDDSUU tdd_test_params{true, {subcarrier_spacing::kHz30, {10, 8, 5, 1, 4}}}, // DDDDDDDDSU tdd_test_params{false, {subcarrier_spacing::kHz30, {6, 3, 5, 2, 0}, tdd_ul_dl_pattern{4, 4, 0, 0, 0}}}, - tdd_test_params{true, {subcarrier_spacing::kHz30, {4, 2, 9, 1, 0}}} // DDSU + tdd_test_params{true, {subcarrier_spacing::kHz30, {4, 2, 9, 1, 0}}}, // DDSU + // UL heavy + tdd_test_params{true, {subcarrier_spacing::kHz30, {10, 4, 5, 5, 0}}}, // DDDDSUUUUU + tdd_test_params{true, {subcarrier_spacing::kHz30, {10, 3, 5, 6, 0}}}, + tdd_test_params{true, {subcarrier_spacing::kHz30, {10, 2, 10, 7, 0}}, 2} )); // DDDSUUDDDD // clang-format on From a9975f8483e8de42ce1c304081a714d916ae7153 Mon Sep 17 00:00:00 2001 From: asaezper Date: Wed, 18 Sep 2024 12:11:13 +0200 Subject: [PATCH 075/174] ci: adjust viavi tests criteria --- .gitlab/ci/e2e.yml | 3 - tests/e2e/tests/viavi/test_declaration.yml | 92 +++++++++---------- .../tests/viavi/test_declaration_debug.yml | 8 +- 3 files changed, 47 insertions(+), 56 deletions(-) diff --git a/.gitlab/ci/e2e.yml b/.gitlab/ci/e2e.yml index 5e32b7573b..4ffe3ccda4 100644 --- a/.gitlab/ci/e2e.yml +++ b/.gitlab/ci/e2e.yml @@ -602,7 +602,6 @@ viavi: - job: "basic avx512 dpdk" artifacts: true - *retina-needs - allow_failure: true parallel: matrix: - KEYWORDS: [ @@ -619,7 +618,6 @@ viavi-extended: extends: .viavi rules: - if: $CI_DESCRIPTION =~ /Weekly/ - allow_failure: true needs: - job: "basic avx512 dpdk" artifacts: true @@ -634,7 +632,6 @@ viavi-debug: extends: .viavi variables: MARKERS: "viavi_debug" - allow_failure: true needs: - job: "basic avx512 dpdk withassert" artifacts: true diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index d53b405b0e..98b1dae927 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -21,10 +21,6 @@ campaign_filename: &campaign_filename "C:\\ci\\CI 4x4 ORAN-FH-complete.xml" gnb_extra_commands: &gnb_extra_commands "ru_ofh --ta4_max 700 --ta4_min 10" -expected_dl_bitrate_high: &expected_dl_bitrate_high 1200000000 -expected_ul_bitrate_high: &expected_ul_bitrate_high 80000000 -expected_dl_bitrate_low: &expected_dl_bitrate_low 14000 -expected_ul_bitrate_low: &expected_ul_bitrate_low 1000 test_timeout: &test_timeout 2700 # 45 * 60 tests: @@ -37,9 +33,9 @@ tests: max_puschs_per_slot: 8 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_high - expected_ul_bitrate: *expected_ul_bitrate_high - fail_if_kos: false + expected_dl_bitrate: 1.2e+9 + expected_ul_bitrate: 80.0e+6 + fail_if_kos: true warning_as_errors: true - campaign_filename: *campaign_filename @@ -51,9 +47,9 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_high - expected_ul_bitrate: *expected_ul_bitrate_high - fail_if_kos: false + expected_dl_bitrate: 1.2e+9 + expected_ul_bitrate: 80.0e+6 + fail_if_kos: true warning_as_errors: true - campaign_filename: *campaign_filename @@ -65,9 +61,9 @@ tests: max_puschs_per_slot: 8 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low - fail_if_kos: false + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 + fail_if_kos: true warning_as_errors: true - campaign_filename: *campaign_filename @@ -79,8 +75,8 @@ tests: max_puschs_per_slot: 8 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 fail_if_kos: false warning_as_errors: true @@ -93,9 +89,9 @@ tests: max_puschs_per_slot: 8 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low - fail_if_kos: false + expected_dl_bitrate: 1.0e+9 + expected_ul_bitrate: 1.0e+3 + fail_if_kos: true warning_as_errors: true - campaign_filename: *campaign_filename @@ -107,9 +103,9 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low - fail_if_kos: false + expected_dl_bitrate: 1.0e+9 + expected_ul_bitrate: 1.0e+3 + fail_if_kos: true warning_as_errors: true - campaign_filename: *campaign_filename @@ -121,8 +117,8 @@ tests: max_puschs_per_slot: 8 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 fail_if_kos: false warning_as_errors: true @@ -135,8 +131,8 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: 1 - expected_ul_bitrate: 1 + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 fail_if_kos: false warning_as_errors: false @@ -149,9 +145,9 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low - fail_if_kos: false + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 + fail_if_kos: true warning_as_errors: true # - campaign_filename: *campaign_filename @@ -163,8 +159,8 @@ tests: # max_puschs_per_slot: 4 # enable_qos_viavi: false # # test/fail criteria - # expected_dl_bitrate: *expected_dl_bitrate_low - # expected_ul_bitrate: *expected_ul_bitrate_low + # expected_dl_bitrate: 14.0e+3 + # expected_ul_bitrate: 1.0e+3 # fail_if_kos: false # warning_as_errors: false @@ -177,9 +173,9 @@ tests: max_puschs_per_slot: 8 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low - fail_if_kos: false + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 + fail_if_kos: true warning_as_errors: true # - campaign_filename: *campaign_filename @@ -191,23 +187,23 @@ tests: # max_puschs_per_slot: 4 # enable_qos_viavi: false # # test/fail criteria - # expected_dl_bitrate: *expected_dl_bitrate_low - # expected_ul_bitrate: *expected_ul_bitrate_low - # fail_if_kos: false + # expected_dl_bitrate: 14.0e+3 + # expected_ul_bitrate: 1.0e+3 + # fail_if_kos: true # warning_as_errors: true - campaign_filename: *campaign_filename test_name: "32UE ideal ping" test_timeout: *test_timeout - gnb_extra_commands: "log --all_level=info --rlc_level=warning" + gnb_extra_commands: *gnb_extra_commands id: "32UE ideal ping" max_pdschs_per_slot: 1 max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low - fail_if_kos: false + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 + fail_if_kos: true warning_as_errors: true - campaign_filename: *campaign_filename @@ -219,9 +215,9 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_low - expected_ul_bitrate: *expected_ul_bitrate_low - fail_if_kos: false + expected_dl_bitrate: 14.0e+3 + expected_ul_bitrate: 1.0e+3 + fail_if_kos: true warning_as_errors: true - campaign_filename: *campaign_filename @@ -233,8 +229,8 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_high - expected_ul_bitrate: *expected_ul_bitrate_high + expected_dl_bitrate: 1.2e+9 + expected_ul_bitrate: 80.0e+6 fail_if_kos: false warning_as_errors: false @@ -247,7 +243,7 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_high - expected_ul_bitrate: *expected_ul_bitrate_high + expected_dl_bitrate: 1.2e+9 + expected_ul_bitrate: 80.0e+6 fail_if_kos: false - warning_as_errors: false \ No newline at end of file + warning_as_errors: false diff --git a/tests/e2e/tests/viavi/test_declaration_debug.yml b/tests/e2e/tests/viavi/test_declaration_debug.yml index 73630164b3..993c626ac2 100644 --- a/tests/e2e/tests/viavi/test_declaration_debug.yml +++ b/tests/e2e/tests/viavi/test_declaration_debug.yml @@ -21,8 +21,6 @@ campaign_filename: &campaign_filename "C:\\ci\\CI 4x4 ORAN-FH-complete.xml" gnb_extra_commands: &gnb_extra_commands "" -expected_dl_bitrate_high: &expected_dl_bitrate_high 80000000 -expected_ul_bitrate_high: &expected_ul_bitrate_high 80000000 tests: - campaign_filename: *campaign_filename @@ -34,7 +32,7 @@ tests: max_puschs_per_slot: 4 enable_qos_viavi: false # test/fail criteria - expected_dl_bitrate: *expected_dl_bitrate_high - expected_ul_bitrate: *expected_ul_bitrate_high - fail_if_kos: false + expected_dl_bitrate: 1.2e+9 + expected_ul_bitrate: 80.0e+6 + fail_if_kos: true warning_as_errors: false From c556f69d8089647717d2e89b8763c3ed16871c5c Mon Sep 17 00:00:00 2001 From: asaezper Date: Wed, 18 Sep 2024 12:57:18 +0200 Subject: [PATCH 076/174] ci: don't allow KOs in long viavi tests --- tests/e2e/tests/viavi/test_declaration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index 98b1dae927..f61a3f1de0 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -231,7 +231,7 @@ tests: # test/fail criteria expected_dl_bitrate: 1.2e+9 expected_ul_bitrate: 80.0e+6 - fail_if_kos: false + fail_if_kos: true warning_as_errors: false - campaign_filename: *campaign_filename @@ -245,5 +245,5 @@ tests: # test/fail criteria expected_dl_bitrate: 1.2e+9 expected_ul_bitrate: 80.0e+6 - fail_if_kos: false + fail_if_kos: true warning_as_errors: false From e1f93da55beffd53711361b3a70fe31b5c9d1535 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Wed, 18 Sep 2024 11:34:40 +0200 Subject: [PATCH 077/174] fapi: logging ta in nano seconds --- lib/fapi/loggers/message_loggers.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/fapi/loggers/message_loggers.cpp b/lib/fapi/loggers/message_loggers.cpp index baf7dbde57..a7dc477600 100644 --- a/lib/fapi/loggers/message_loggers.cpp +++ b/lib/fapi/loggers/message_loggers.cpp @@ -48,7 +48,7 @@ void srsran::fapi::log_crc_indication(const crc_indication_message& msg, srslog: fmt::format_to( buffer, "\n\t- CRC rnti={} harq_id={} tb_status={}", pdu.rnti, pdu.harq_id, pdu.tb_crc_status_ok ? "OK" : "KO"); if (pdu.timing_advance_offset_ns != std::numeric_limits::min()) { - fmt::format_to(buffer, " ta_s={:.1f}", pdu.timing_advance_offset_ns * 1e-9F); + fmt::format_to(buffer, " ta_ns={}", pdu.timing_advance_offset_ns); } if (pdu.ul_sinr_metric != std::numeric_limits::min()) { fmt::format_to(buffer, " sinr={:.1f}", to_crc_ul_sinr(pdu.ul_sinr_metric)); @@ -183,7 +183,7 @@ void srsran::fapi::log_rach_indication(const rach_indication_message& msg, srslo fmt::format_to(buffer, "\n\t\t- PREAMBLE index={}", preamble.preamble_index); if (preamble.timing_advance_offset_ns != std::numeric_limits::max()) { - fmt::format_to(buffer, " ta_s={:.1f}", preamble.timing_advance_offset_ns * 1e-9F); + fmt::format_to(buffer, " ta_ns={}", preamble.timing_advance_offset_ns); } if (preamble.preamble_pwr != std::numeric_limits::max()) { fmt::format_to(buffer, " pwr={:.1f}", to_rach_preamble_power_dB(preamble.preamble_pwr)); @@ -235,7 +235,7 @@ static void log_uci_pucch_f0_f1_pdu(const uci_pucch_pdu_format_0_1& pdu, fmt::me fmt::format_to(buffer, " sinr={:.1f}", to_uci_ul_sinr(pdu.ul_sinr_metric)); } if (pdu.timing_advance_offset_ns != std::numeric_limits::min()) { - fmt::format_to(buffer, " ta_s={:.1f}", pdu.timing_advance_offset_ns * 1e-9F); + fmt::format_to(buffer, " ta_ns={}", pdu.timing_advance_offset_ns); } if (pdu.rsrp != std::numeric_limits::max()) { fmt::format_to(buffer, " rsrp={:.1f}", to_uci_ul_rsrp(pdu.rsrp)); @@ -267,7 +267,7 @@ static void log_uci_pucch_f234_pdu(const uci_pucch_pdu_format_2_3_4& pdu, fmt::m fmt::format_to(buffer, " sinr={:.1f}", to_uci_ul_sinr(pdu.ul_sinr_metric)); } if (pdu.timing_advance_offset_ns != std::numeric_limits::min()) { - fmt::format_to(buffer, " ta_s={:.1f}", pdu.timing_advance_offset_ns * 1e-9F); + fmt::format_to(buffer, " ta_ns={}", pdu.timing_advance_offset_ns); } if (pdu.rsrp != std::numeric_limits::max()) { fmt::format_to(buffer, " rsrp={:.1f}", to_uci_ul_rsrp(pdu.rsrp)); @@ -293,7 +293,7 @@ static void log_uci_pusch_pdu(const uci_pusch_pdu& pdu, fmt::memory_buffer& buff fmt::format_to(buffer, " sinr={:.1f}", to_uci_ul_sinr(pdu.ul_sinr_metric)); } if (pdu.timing_advance_offset_ns != std::numeric_limits::min()) { - fmt::format_to(buffer, " ta_s={:.1f}", pdu.timing_advance_offset_ns * 1e-9F); + fmt::format_to(buffer, " ta_ns={}", pdu.timing_advance_offset_ns); } if (pdu.rsrp != std::numeric_limits::max()) { fmt::format_to(buffer, " rsrp={:.1f}", to_uci_ul_rsrp(pdu.rsrp)); From a2b7a773ac66328618aed7a71e953135465a6822 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Wed, 18 Sep 2024 11:00:09 +0200 Subject: [PATCH 078/174] sched: fix clearing of PUSCH RB count per slot in case of skipped slots --- lib/scheduler/slicing/ran_slice_candidate.h | 4 ++-- lib/scheduler/slicing/ran_slice_instance.cpp | 16 +++++++++++-- lib/scheduler/slicing/ran_slice_instance.h | 11 ++++----- lib/scheduler/slicing/slice_scheduler.cpp | 25 ++++++++++++++------ 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/lib/scheduler/slicing/ran_slice_candidate.h b/lib/scheduler/slicing/ran_slice_candidate.h index f43e4a66c6..c329e86732 100644 --- a/lib/scheduler/slicing/ran_slice_candidate.h +++ b/lib/scheduler/slicing/ran_slice_candidate.h @@ -50,9 +50,9 @@ class common_ran_slice_candidate if constexpr (IsDl) { return max_rbs < inst->pdsch_rb_count ? 0 : max_rbs - inst->pdsch_rb_count; } - return max_rbs < inst->pusch_rb_count_per_slot[slot_tx.to_uint()] + return max_rbs < inst->pusch_rb_count_per_slot[slot_tx.to_uint() % inst->pusch_rb_count_per_slot.size()] ? 0 - : max_rbs - inst->pusch_rb_count_per_slot[slot_tx.to_uint()]; + : max_rbs - inst->pusch_rb_count_per_slot[slot_tx.to_uint() % inst->pusch_rb_count_per_slot.size()]; } /// Returns slot at which PUSCH/PDSCH needs to be scheduled for this slice candidate. diff --git a/lib/scheduler/slicing/ran_slice_instance.cpp b/lib/scheduler/slicing/ran_slice_instance.cpp index ee8a9ada0e..15fc12b208 100644 --- a/lib/scheduler/slicing/ran_slice_instance.cpp +++ b/lib/scheduler/slicing/ran_slice_instance.cpp @@ -15,7 +15,10 @@ using namespace srsran; ran_slice_instance::ran_slice_instance(ran_slice_id_t id_, const cell_configuration& cell_cfg_, const slice_rrm_policy_config& cfg_) : - id(id_), cell_cfg(&cell_cfg_), cfg(cfg_) + id(id_), + cell_cfg(&cell_cfg_), + cfg(cfg_), + pusch_rb_count_per_slot(get_allocator_ring_size_gt_min(SCHEDULER_MAX_K2 + cell_cfg->ntn_cs_koffset)) { std::fill(pusch_rb_count_per_slot.begin(), pusch_rb_count_per_slot.end(), 0); } @@ -25,7 +28,16 @@ void ran_slice_instance::slot_indication(slot_point slot_tx) pdsch_rb_count = 0; // Clear RB count in previous slots. for (unsigned count = 0; count < nof_slots_to_clear; ++count) { - pusch_rb_count_per_slot[(slot_tx - 1 - count).to_uint()] = 0; + pusch_rb_count_per_slot[(slot_tx - 1 - count).to_uint() % pusch_rb_count_per_slot.size()] = 0; + } +} + +void ran_slice_instance::skipped_slot_indication(slot_point prev_slot, slot_point current_slot) +{ + slot_point sl = current_slot - 1; + while (sl > prev_slot) { + slot_indication(sl); + sl -= nof_slots_to_clear; } } diff --git a/lib/scheduler/slicing/ran_slice_instance.h b/lib/scheduler/slicing/ran_slice_instance.h index fc76e7a509..e5da73582b 100644 --- a/lib/scheduler/slicing/ran_slice_instance.h +++ b/lib/scheduler/slicing/ran_slice_instance.h @@ -22,15 +22,14 @@ namespace srsran { /// This class stores all the internal information relative to a RAN slice instantiation. class ran_slice_instance { - /// Number of slots for which allocated PUSCH grant is maintained. - static const size_t RING_ALLOCATOR_SIZE = - get_allocator_ring_size_gt_min(SCHEDULER_MAX_K2 + NTN_CELL_SPECIFIC_KOFFSET_MAX); - public: ran_slice_instance(ran_slice_id_t id_, const cell_configuration& cell_cfg_, const slice_rrm_policy_config& cfg_); void slot_indication(slot_point slot_tx); + /// \brief Handle skipped slot indication. + void skipped_slot_indication(slot_point prev_slot, slot_point current_slot); + bool active() const { return not slice_ues.empty(); } /// Save PDSCH grant. @@ -39,7 +38,7 @@ class ran_slice_instance /// Save PUSCH grant. void store_pusch_grant(unsigned crbs, slot_point pusch_slot) { - pusch_rb_count_per_slot[pusch_slot.to_uint()] += crbs; + pusch_rb_count_per_slot[pusch_slot.to_uint() % pusch_rb_count_per_slot.size()] += crbs; } /// Determine if at least one bearer of the given UE is currently managed by this slice. @@ -74,7 +73,7 @@ class ran_slice_instance /// Counter of how many RBs have been scheduled for PDSCH in the current slot for this slice. unsigned pdsch_rb_count = 0; /// Ring of counters of how many RBs have been scheduled for PUSCH in a particular slot for this slice. - circular_array pusch_rb_count_per_slot; + std::vector pusch_rb_count_per_slot; /// Nof. of previous slots in which RB count needs to be cleared in \c pusch_rb_count_per_slot upon receiving slot /// indication. diff --git a/lib/scheduler/slicing/slice_scheduler.cpp b/lib/scheduler/slicing/slice_scheduler.cpp index 541dfd4619..c9471c47d8 100644 --- a/lib/scheduler/slicing/slice_scheduler.cpp +++ b/lib/scheduler/slicing/slice_scheduler.cpp @@ -61,6 +61,13 @@ slice_scheduler::slice_scheduler(const cell_configuration& cell_cfg_, ue_reposit void slice_scheduler::slot_indication(slot_point slot_tx) { + // If there are skipped slots, handle them. + if ((current_slot + 1) != slot_tx) { + for (auto& slice : slices) { + slice.inst.skipped_slot_indication(current_slot, slot_tx); + } + } + // Update current slot. current_slot = slot_tx; slot_count++; @@ -88,14 +95,14 @@ void slice_scheduler::slot_indication(slot_point slot_tx) for (const unsigned pusch_td_res_idx : valid_pusch_td_list_per_slot[slot_tx.to_uint() % valid_pusch_td_list_per_slot.size()]) { slot_point pusch_slot = slot_tx + pusch_time_domain_list[pusch_td_res_idx].k2; - max_rbs = slice.inst.pusch_rb_count_per_slot[pusch_slot.to_uint()] <= slice.inst.cfg.min_prb and - slice.inst.cfg.min_prb > 0 - ? slice.inst.cfg.min_prb - : slice.inst.cfg.max_prb; + unsigned pusch_rb_count = + slice.inst.pusch_rb_count_per_slot[pusch_slot.to_uint() % slice.inst.pusch_rb_count_per_slot.size()]; + max_rbs = pusch_rb_count <= slice.inst.cfg.min_prb and slice.inst.cfg.min_prb > 0 ? slice.inst.cfg.min_prb + : slice.inst.cfg.max_prb; ul_prio_queue.push( slice_candidate_context{slice.inst.id, slice.get_prio(false, slot_count, slot_tx, pusch_slot, slices.size(), false), - {slice.inst.pusch_rb_count_per_slot[pusch_slot.to_uint()], max_rbs}, + {pusch_rb_count, max_rbs}, pusch_slot}); } } @@ -232,7 +239,10 @@ slice_scheduler::get_next_candidate() prio_queue.pop(); unsigned rb_count = - IsDownlink ? chosen_slice.inst.pdsch_rb_count : chosen_slice.inst.pusch_rb_count_per_slot[pxsch_slot.to_uint()]; + IsDownlink + ? chosen_slice.inst.pdsch_rb_count + : chosen_slice.inst + .pusch_rb_count_per_slot[pxsch_slot.to_uint() % chosen_slice.inst.pusch_rb_count_per_slot.size()]; if (not rb_lims.contains(rb_count)) { // The slice has been scheduled in this slot with a number of RBs that is not within the limits for this // candidate. This could happen, for instance, if the scheduler could not schedule all RBs of a candidate @@ -294,7 +304,8 @@ slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_pri static constexpr priority_type delay_bitsize = 8U; static constexpr priority_type rr_bitsize = 8U; - unsigned rb_count = is_dl ? inst.pdsch_rb_count : inst.pusch_rb_count_per_slot[pxsch_slot.to_uint()]; + unsigned rb_count = is_dl ? inst.pdsch_rb_count + : inst.pusch_rb_count_per_slot[pxsch_slot.to_uint() % inst.pusch_rb_count_per_slot.size()]; if (not inst.active() or rb_count >= inst.cfg.max_prb) { // If the slice is not in a state to be scheduled in this slot, return skip priority level. return skip_prio; From e0f1498cbf7f2eb0ed35edac673c74ad3c9ebddd Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Thu, 19 Sep 2024 12:23:53 +0200 Subject: [PATCH 079/174] sched: refactor handling of skipped slot indication in a RAN slice instance --- lib/scheduler/slicing/ran_slice_instance.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/scheduler/slicing/ran_slice_instance.cpp b/lib/scheduler/slicing/ran_slice_instance.cpp index 15fc12b208..6cb19c7184 100644 --- a/lib/scheduler/slicing/ran_slice_instance.cpp +++ b/lib/scheduler/slicing/ran_slice_instance.cpp @@ -27,6 +27,8 @@ void ran_slice_instance::slot_indication(slot_point slot_tx) { pdsch_rb_count = 0; // Clear RB count in previous slots. + // NOTE: RB count in \c nof_slots_to_clear number of slots are cleared because \c slot_indication() is called only + // during DL slots. for (unsigned count = 0; count < nof_slots_to_clear; ++count) { pusch_rb_count_per_slot[(slot_tx - 1 - count).to_uint() % pusch_rb_count_per_slot.size()] = 0; } @@ -34,11 +36,12 @@ void ran_slice_instance::slot_indication(slot_point slot_tx) void ran_slice_instance::skipped_slot_indication(slot_point prev_slot, slot_point current_slot) { - slot_point sl = current_slot - 1; - while (sl > prev_slot) { - slot_indication(sl); - sl -= nof_slots_to_clear; - } + slot_point sl = prev_slot; + do { + sl += nof_slots_to_clear; + // Clear only until current slot so that RB count in future slots are not lost. + slot_indication(std::min(sl, current_slot)); + } while (sl < current_slot); } void ran_slice_instance::rem_logical_channel(du_ue_index_t ue_idx, lcid_t lcid) From 7e0d91fe3efc379eb3d7a94ede7cda9946d1b044 Mon Sep 17 00:00:00 2001 From: Robert Falkenberg Date: Thu, 19 Sep 2024 11:41:24 +0200 Subject: [PATCH 080/174] cmake,phy: build PDSCH tests only if USE_PHY_TESTVECTORS enabled --- .../channel_processors/pdsch/CMakeLists.txt | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt b/tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt index ef70e5439e..32b12ca54f 100644 --- a/tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt +++ b/tests/unittests/phy/upper/channel_processors/pdsch/CMakeLists.txt @@ -26,29 +26,30 @@ target_link_libraries(pdsch_processor_validator_test gtest_main) add_test(pdsch_processor_validator_test pdsch_processor_validator_test) -add_executable(pdsch_encoder_test pdsch_encoder_test.cpp) -set(PDSCH_ENCODER_LIBRARIES srsran_channel_processors srslog) +if (USE_PHY_TESTVECTORS) + add_executable(pdsch_encoder_test pdsch_encoder_test.cpp) + set(PDSCH_ENCODER_LIBRARIES srsran_channel_processors srslog) -if (ENABLE_PDSCH_HWACC) - set_source_files_properties(pdsch_encoder_test.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") - list(APPEND PDSCH_ENCODER_LIBRARIES hal_hwacc_pdsch) -endif (ENABLE_PDSCH_HWACC) + if (ENABLE_PDSCH_HWACC) + set_source_files_properties(pdsch_encoder_test.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") + list(APPEND PDSCH_ENCODER_LIBRARIES hal_hwacc_pdsch) + endif (ENABLE_PDSCH_HWACC) -target_link_libraries(pdsch_encoder_test ${PDSCH_ENCODER_LIBRARIES}) -add_test_vector(pdsch_encoder_test pdsch_encoder_test_data.tar.gz "") + target_link_libraries(pdsch_encoder_test ${PDSCH_ENCODER_LIBRARIES}) + add_test_vector(pdsch_encoder_test pdsch_encoder_test_data.tar.gz "") -add_executable(pdsch_modulator_test pdsch_modulator_test.cpp) -target_link_libraries(pdsch_modulator_test srsran_channel_processors srslog) -add_test_vector(pdsch_modulator_test pdsch_modulator_test_data.tar.gz "") + add_executable(pdsch_modulator_test pdsch_modulator_test.cpp) + target_link_libraries(pdsch_modulator_test srsran_channel_processors srslog) + add_test_vector(pdsch_modulator_test pdsch_modulator_test_data.tar.gz "") -add_executable(pdsch_processor_vectortest pdsch_processor_vectortest.cpp) -set(PDSCH_PROCESSOR_LIBRARIES srsran_channel_processors srslog gtest gtest_main) + add_executable(pdsch_processor_vectortest pdsch_processor_vectortest.cpp) + set(PDSCH_PROCESSOR_LIBRARIES srsran_channel_processors srslog gtest gtest_main) -if (ENABLE_PDSCH_HWACC) - set_source_files_properties(pdsch_processor_vectortest.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") - list(APPEND PDSCH_PROCESSOR_LIBRARIES hal_hwacc_pdsch) -endif (ENABLE_PDSCH_HWACC) - -target_link_libraries(pdsch_processor_vectortest ${PDSCH_PROCESSOR_LIBRARIES}) -add_test_vector(pdsch_processor_vectortest pdsch_processor_test_data.tar.gz "") + if (ENABLE_PDSCH_HWACC) + set_source_files_properties(pdsch_processor_vectortest.cpp PROPERTIES COMPILE_DEFINITIONS "HWACC_PDSCH_ENABLED") + list(APPEND PDSCH_PROCESSOR_LIBRARIES hal_hwacc_pdsch) + endif (ENABLE_PDSCH_HWACC) + target_link_libraries(pdsch_processor_vectortest ${PDSCH_PROCESSOR_LIBRARIES}) + add_test_vector(pdsch_processor_vectortest pdsch_processor_test_data.tar.gz "") +endif (USE_PHY_TESTVECTORS) From 2b009eb8caa918791656b9d81b02dce12e95f5fa Mon Sep 17 00:00:00 2001 From: asaezper Date: Thu, 19 Sep 2024 12:02:24 +0200 Subject: [PATCH 081/174] ci: enable rlc metrics in viavi and fix fail_if_kos --- .gitlab/ci/e2e/.env | 2 +- tests/e2e/tests/viavi.py | 1 + tests/e2e/tests/viavi/test_declaration.yml | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitlab/ci/e2e/.env b/.gitlab/ci/e2e/.env index 3acd758a4d..a8879bac86 100644 --- a/.gitlab/ci/e2e/.env +++ b/.gitlab/ci/e2e/.env @@ -1,6 +1,6 @@ SRSGNB_REGISTRY_URI=registry.gitlab.com/softwareradiosystems/srsgnb RETINA_REGISTRY_PREFIX=registry.gitlab.com/softwareradiosystems/ci/retina -RETINA_VERSION=0.52.20 +RETINA_VERSION=0.52.23 UBUNTU_VERSION=24.04 AMARISOFT_VERSION=2023-09-08 SRSUE_VERSION=23.11 diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index a3a92b71e9..baf7e8ec87 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -335,6 +335,7 @@ def _test_viavi( "enable_qos_viavi": test_declaration.enable_qos_viavi, "nof_antennas_dl": 4, "nof_antennas_ul": 1, + "rlc_metrics": True, }, }, } diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index f61a3f1de0..e032ac35f5 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -63,7 +63,7 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: true + fail_if_kos: false warning_as_errors: true - campaign_filename: *campaign_filename @@ -175,7 +175,7 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: true + fail_if_kos: false warning_as_errors: true # - campaign_filename: *campaign_filename From 8decadcdc0681549f2993eb203d58b1b0df9b36d Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 19 Sep 2024 17:59:59 +0200 Subject: [PATCH 082/174] mac: remove race condition in test mode --- .../adapters/mac_test_mode_adapter.cpp | 67 ++++++++++--------- .../du_high/adapters/mac_test_mode_adapter.h | 66 +++++++++--------- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp index de52d83d8e..5c170f9bf2 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.cpp @@ -366,37 +366,6 @@ void mac_test_mode_cell_adapter::forward_uci_ind_to_mac(const mac_uci_indication // Forward UCI indication to real MAC. adapted.handle_uci(uci_msg); - - // Update buffer states. - for (const mac_uci_pdu& pdu : uci_msg.ucis) { - if (ue_info_mgr.is_test_ue(pdu.rnti) and std::holds_alternative(pdu.pdu)) { - const auto& f1_ind = std::get(pdu.pdu); - - if (not f1_ind.harq_info.has_value()) { - continue; - } - - // In case of PUCCH F1 with HARQ-ACK bits, we assume that the Msg4 has been received. At this point, we - // update the test UE with positive DL buffer states and BSR. - if (not ue_info_mgr.is_msg4_rxed(pdu.rnti)) { - if (test_ue_cfg.pdsch_active) { - // Update DL buffer state automatically. - dl_bs_notifier(pdu.rnti); - } - - if (test_ue_cfg.pusch_active) { - auto rx_pdu = create_test_pdu_with_bsr(uci_msg.sl_rx, pdu.rnti, to_harq_id(0)); - if (not rx_pdu.has_value()) { - logger.warning("TEST_MODE c-rnti={}: Unable to create test PDU with BSR", pdu.rnti); - continue; - } - // In case of PUSCH test mode is enabled, push a BSR to trigger the first PUSCH. - pdu_handler.handle_rx_data_indication(std::move(rx_pdu.value())); - } - ue_info_mgr.msg4_rxed(pdu.rnti, true); - } - } - } } void mac_test_mode_cell_adapter::forward_crc_ind_to_mac(const mac_crc_indication_message& crc_msg) @@ -513,6 +482,37 @@ void mac_test_mode_cell_adapter::on_new_uplink_scheduler_results(const mac_ul_sc } } + if (ul_res.ul_res != nullptr and not ul_res.ul_res->pucchs.empty()) { + for (const pucch_info& pucch : ul_res.ul_res->pucchs) { + if (not ue_info_mgr.is_test_ue(pucch.crnti) or ue_info_mgr.is_msg4_rxed(pucch.crnti)) { + // UE is not test mode or it has already received Msg4. + continue; + } + if ((pucch.format == pucch_format::FORMAT_1 and pucch.format_1.harq_ack_nof_bits > 0) or + (pucch.format == pucch_format::FORMAT_0 and pucch.format_0.harq_ack_nof_bits > 0)) { + // In case of PUCCH F1 with HARQ-ACK bits, we assume that the Msg4 is received. At this point, we + // update the test UE with positive DL buffer states and BSR. + if (test_ue_cfg.pdsch_active) { + // Update DL buffer state automatically. + dl_bs_notifier(pucch.crnti); + } + + if (test_ue_cfg.pusch_active) { + auto rx_pdu = create_test_pdu_with_bsr(ul_res.slot, pucch.crnti, to_harq_id(0)); + if (not rx_pdu.has_value()) { + logger.warning("TEST_MODE c-rnti={}: Unable to create test PDU with BSR", pucch.crnti); + continue; + } + // In case of PUSCH test mode is enabled, push a BSR to trigger the first PUSCH. + pdu_handler.handle_rx_data_indication(std::move(rx_pdu.value())); + } + + // Mark Msg4 received for the UE. + ue_info_mgr.msg4_rxed(pucch.crnti, true); + } + } + } + // Forward results to PHY. result_notifier.on_new_uplink_scheduler_results(ul_res); } @@ -576,6 +576,7 @@ void phy_test_mode_adapter::phy_cell::on_new_downlink_data(const mac_dl_data_res { ptr->on_new_downlink_data(dl_data); } + void phy_test_mode_adapter::phy_cell::on_new_uplink_scheduler_results(const mac_ul_sched_result& ul_res) { ptr->on_new_uplink_scheduler_results(ul_res); @@ -590,8 +591,8 @@ void phy_test_mode_adapter::phy_cell::on_cell_results_completion(slot_point slot mac_test_mode_adapter::mac_test_mode_adapter(const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg_, mac_result_notifier& phy_notifier_) : test_ue(test_ue_cfg_), - phy_notifier(std::make_unique(phy_notifier_)), - ue_info_mgr(test_ue.rnti, test_ue.nof_ues) + ue_info_mgr(test_ue.rnti, test_ue.nof_ues), + phy_notifier(std::make_unique(phy_notifier_)) { } diff --git a/lib/du/du_high/adapters/mac_test_mode_adapter.h b/lib/du/du_high/adapters/mac_test_mode_adapter.h index 8f04f360fe..9540dac2a2 100644 --- a/lib/du/du_high/adapters/mac_test_mode_adapter.h +++ b/lib/du/du_high/adapters/mac_test_mode_adapter.h @@ -20,34 +20,6 @@ namespace srsran { namespace srs_du { -class phy_test_mode_adapter : public mac_result_notifier -{ -public: - phy_test_mode_adapter(mac_result_notifier& phy_notifier_) : adapted_phy(phy_notifier_), cells(MAX_NOF_DU_CELLS) {} - - mac_cell_result_notifier& get_cell(du_cell_index_t cell_index) override; - - void connect(du_cell_index_t cell_index, mac_cell_result_notifier& test_mode_cell_notifier); - - void disconnect(du_cell_index_t cell_index); - - mac_result_notifier& adapted_phy; - -private: - class phy_cell final : public mac_cell_result_notifier - { - public: - mac_cell_result_notifier* ptr = nullptr; - - void on_new_downlink_scheduler_results(const mac_dl_sched_result& dl_res) override; - void on_new_downlink_data(const mac_dl_data_result& dl_data) override; - void on_new_uplink_scheduler_results(const mac_ul_sched_result& ul_res) override; - void on_cell_results_completion(slot_point slot) override; - }; - - std::vector cells; -}; - /// \brief Handles information related to the test UE(s). class test_ue_info_manager { @@ -82,7 +54,7 @@ class test_ue_info_manager } } - sched_ue_config_request get_sched_ue_cfg_request(rnti_t rnti) const + const sched_ue_config_request& get_sched_ue_cfg_request(rnti_t rnti) const { return rnti_to_ue_info_lookup.at(rnti).sched_ue_cfg_req; } @@ -109,14 +81,42 @@ class test_ue_info_manager bool msg4_rx_flag; }; - /// Parameters received from configuration. + // Parameters received from configuration. rnti_t rnti_start; uint16_t nof_ues; - /// Mapping between UE RNTI and test UE information. + // Mapping between UE RNTI and test UE information. std::unordered_map rnti_to_ue_info_lookup; }; +class phy_test_mode_adapter : public mac_result_notifier +{ +public: + phy_test_mode_adapter(mac_result_notifier& phy_notifier_) : adapted_phy(phy_notifier_), cells(MAX_NOF_DU_CELLS) {} + + mac_cell_result_notifier& get_cell(du_cell_index_t cell_index) override; + + void connect(du_cell_index_t cell_index, mac_cell_result_notifier& test_mode_cell_notifier); + + void disconnect(du_cell_index_t cell_index); + + mac_result_notifier& adapted_phy; + +private: + class phy_cell final : public mac_cell_result_notifier + { + public: + mac_cell_result_notifier* ptr = nullptr; + + void on_new_downlink_scheduler_results(const mac_dl_sched_result& dl_res) override; + void on_new_downlink_data(const mac_dl_data_result& dl_data) override; + void on_new_uplink_scheduler_results(const mac_ul_sched_result& ul_res) override; + void on_cell_results_completion(slot_point slot) override; + }; + + std::vector cells; +}; + /// \brief Adapter of MAC cell for testing purposes. It automatically forces ACK/CRC=OK for the test UE. class mac_test_mode_cell_adapter : public mac_cell_control_information_handler, public mac_cell_result_notifier, @@ -248,11 +248,11 @@ class mac_test_mode_adapter final : public mac_interface, srs_du::du_test_mode_config::test_mode_ue_config test_ue; std::unique_ptr mac_adapted; + test_ue_info_manager ue_info_mgr; + std::unique_ptr phy_notifier; std::vector> cell_info_handler; - - test_ue_info_manager ue_info_mgr; }; } // namespace srs_du From 228ba2d8011b796b6033ef1abb257f5830754654 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Tue, 17 Sep 2024 09:48:39 +0200 Subject: [PATCH 083/174] sched: refactor policy scheduler to use new HARQ management to speed up retransmissions --- lib/scheduler/policy/scheduler_policy.h | 8 +- lib/scheduler/policy/scheduler_time_pf.cpp | 6 +- lib/scheduler/policy/scheduler_time_pf.h | 6 +- lib/scheduler/policy/scheduler_time_rr.cpp | 131 +++++++++--------- lib/scheduler/policy/scheduler_time_rr.h | 6 +- .../ue_scheduling/ue_scheduler_impl.cpp | 6 +- .../policy/scheduler_policy_test.cpp | 4 +- 7 files changed, 88 insertions(+), 79 deletions(-) diff --git a/lib/scheduler/policy/scheduler_policy.h b/lib/scheduler/policy/scheduler_policy.h index fad18da323..60209d82d2 100644 --- a/lib/scheduler/policy/scheduler_policy.h +++ b/lib/scheduler/policy/scheduler_policy.h @@ -109,18 +109,22 @@ class scheduler_policy /// gNB resource grid. /// \param[in] res_grid View of the current resource grid occupancy state for all gnb cells. /// \param[in] slice_candidate Slice candidate to be scheduled in the given slot. + /// \param[in] harq_pending_retx_list List of DL HARQs pending retransmission. virtual void dl_sched(ue_pdsch_allocator& pdsch_alloc, const ue_resource_grid_view& res_grid, - dl_ran_slice_candidate& slice_candidate) = 0; + dl_ran_slice_candidate& slice_candidate, + dl_harq_pending_retx_list harq_pending_retx_list) = 0; /// Schedule UE UL grants for a given {slot, cell}. /// \param[out] pusch_alloc PUSCH grant allocator. This object provides a handle to allocate PUSCH grants in the /// gNB resource grid. /// \param[in] res_grid View of the current resource grid occupancy state for all gnb cells. /// \param[in] slice_candidate Slice candidate to be scheduled in the given slot. + /// \param[in] harq_pending_retx_list List of UL HARQs pending retransmission. virtual void ul_sched(ue_pusch_allocator& pusch_alloc, const ue_resource_grid_view& res_grid, - ul_ran_slice_candidate& slice_candidate) = 0; + ul_ran_slice_candidate& slice_candidate, + ul_harq_pending_retx_list harq_pending_retx_list) = 0; }; } // namespace srsran diff --git a/lib/scheduler/policy/scheduler_time_pf.cpp b/lib/scheduler/policy/scheduler_time_pf.cpp index db7ef9f0ff..7e4976f99a 100644 --- a/lib/scheduler/policy/scheduler_time_pf.cpp +++ b/lib/scheduler/policy/scheduler_time_pf.cpp @@ -19,7 +19,8 @@ scheduler_time_pf::scheduler_time_pf(const scheduler_ue_expert_config& expert_cf void scheduler_time_pf::dl_sched(ue_pdsch_allocator& pdsch_alloc, const ue_resource_grid_view& res_grid, - dl_ran_slice_candidate& slice_candidate) + dl_ran_slice_candidate& slice_candidate, + dl_harq_pending_retx_list harq_pending_retx_list) { // Clear the existing contents of the queue. dl_queue.clear(); @@ -64,7 +65,8 @@ void scheduler_time_pf::dl_sched(ue_pdsch_allocator& pdsch_alloc, void scheduler_time_pf::ul_sched(ue_pusch_allocator& pusch_alloc, const ue_resource_grid_view& res_grid, - ul_ran_slice_candidate& slice_candidate) + ul_ran_slice_candidate& slice_candidate, + ul_harq_pending_retx_list harq_pending_retx_list) { // Clear the existing contents of the queue. ul_queue.clear(); diff --git a/lib/scheduler/policy/scheduler_time_pf.h b/lib/scheduler/policy/scheduler_time_pf.h index c5fb263069..d9f509c3f3 100644 --- a/lib/scheduler/policy/scheduler_time_pf.h +++ b/lib/scheduler/policy/scheduler_time_pf.h @@ -21,11 +21,13 @@ class scheduler_time_pf : public scheduler_policy void dl_sched(ue_pdsch_allocator& pdsch_alloc, const ue_resource_grid_view& res_grid, - dl_ran_slice_candidate& slice_candidate) override; + dl_ran_slice_candidate& slice_candidate, + dl_harq_pending_retx_list harq_pending_retx_list) override; void ul_sched(ue_pusch_allocator& pusch_alloc, const ue_resource_grid_view& res_grid, - ul_ran_slice_candidate& slice_candidate) override; + ul_ran_slice_candidate& slice_candidate, + ul_harq_pending_retx_list harq_pending_retx_list) override; private: /// Fairness parameters. diff --git a/lib/scheduler/policy/scheduler_time_rr.cpp b/lib/scheduler/policy/scheduler_time_rr.cpp index 170f711779..2ae550b9c7 100644 --- a/lib/scheduler/policy/scheduler_time_rr.cpp +++ b/lib/scheduler/policy/scheduler_time_rr.cpp @@ -158,27 +158,22 @@ static bool can_allocate_dl_newtx(const slice_ue& ue_ref, ue_cell_index_t cell_i return true; } -/// \brief Fetches list of DL HARQ candidates to schedule. -static static_vector -get_ue_dl_harq_candidates(const slice_ue& ue_ref, ue_cell_index_t cell_index, ran_slice_id_t slice_id) +/// \brief Fetches list of HARQ candidates pending retransmission for a UE. +template +static static_vector, MAX_NOF_HARQS> +get_ue_harq_candidates(du_ue_index_t ue_index, + span> retx_harqs) { - static_vector dl_harq_candidates; + using handle_type = std::conditional_t; - const ue_cell& ue_cc = ue_ref.get_cell(cell_index); - // Create list of DL HARQ processes with pending retx, sorted from oldest to newest. - for (unsigned i = 0; i != ue_cc.harqs.nof_dl_harqs(); ++i) { - std::optional h = ue_cc.harqs.dl_harq(to_harq_id(i)); - if (h.has_value() and h->has_pending_retx() and h->get_grant_params().slice_id == slice_id) { - dl_harq_candidates.push_back(*h); + static_vector harq_candidates; + for (handle_type h : retx_harqs) { + if (h.ue_index() == ue_index) { + harq_candidates.push_back(h); } } - std::sort(dl_harq_candidates.begin(), - dl_harq_candidates.end(), - [](const dl_harq_process_handle& lhs, const dl_harq_process_handle& rhs) { - return lhs.uci_slot() < rhs.uci_slot(); - }); - return dl_harq_candidates; + return harq_candidates; } static bool can_allocate_ul_newtx(const slice_ue& ue_ref, ue_cell_index_t cell_index, srslog::basic_logger& logger) @@ -210,28 +205,6 @@ static bool can_allocate_ul_newtx(const slice_ue& ue_ref, ue_cell_index_t cell_i return true; } -/// \brief Fetches list of UL HARQ candidates to schedule. -static static_vector -get_ue_ul_harq_candidates(const slice_ue& ue_ref, ue_cell_index_t cell_index, ran_slice_id_t slice_id) -{ - static_vector ul_harq_candidates; - - const ue_cell& ue_cc = ue_ref.get_cell(cell_index); - // Create list of UL HARQ processes with pending retx, sorted from oldest to newest. - for (unsigned i = 0; i != ue_cc.harqs.nof_ul_harqs(); ++i) { - std::optional h = ue_cc.harqs.ul_harq(to_harq_id(i)); - if (h.has_value() and h->has_pending_retx() and h->get_grant_params().slice_id == slice_id) { - ul_harq_candidates.push_back(*h); - } - } - std::sort(ul_harq_candidates.begin(), - ul_harq_candidates.end(), - [](const ul_harq_process_handle& lhs, const ul_harq_process_handle& rhs) { - return lhs.pusch_slot() < rhs.pusch_slot(); - }); - return ul_harq_candidates; -} - /// \brief Algorithm to select next UE to allocate in a time-domain RR fashion /// \param[in] ue_db Map of UEs belonging to a slice. /// \param[in] next_ue_index UE index with the highest priority to be allocated. @@ -271,13 +244,13 @@ round_robin_apply(const slice_ue_repository& ue_db, du_ue_index_t next_ue_index, } /// Allocate UE PDSCH grant. -static alloc_result alloc_dl_ue(const slice_ue& u, - const ue_resource_grid_view& res_grid, - ue_pdsch_allocator& pdsch_alloc, - bool is_retx, - srslog::basic_logger& logger, - ran_slice_id_t slice_id, - std::optional dl_new_tx_max_nof_rbs_per_ue_per_slot = {}) +static alloc_result alloc_dl_ue(const slice_ue& u, + const ue_resource_grid_view& res_grid, + ue_pdsch_allocator& pdsch_alloc, + bool is_retx, + srslog::basic_logger& logger, + static_vector retx_harqs, + std::optional dl_new_tx_max_nof_rbs_per_ue_per_slot = {}) { if (not is_retx) { if (not u.has_pending_dl_newtx_bytes()) { @@ -300,7 +273,7 @@ static alloc_result alloc_dl_ue(const slice_ue& u, if (is_retx) { // Get DL HARQ candidates. - const auto harq_candidates = get_ue_dl_harq_candidates(u, to_ue_cell_index(i), slice_id); + const auto harq_candidates = get_ue_harq_candidates(u.ue_index(), retx_harqs); // Iterate through allocation parameter candidates. for (dl_harq_process_handle h_dl : harq_candidates) { ue_pdsch_grant grant{&u, ue_cc.cell_index, h_dl.id()}; @@ -324,12 +297,12 @@ static alloc_result alloc_dl_ue(const slice_ue& u, } /// Allocate UE PUSCH grant. -static alloc_result alloc_ul_ue(const slice_ue& u, - ue_pusch_allocator& pusch_alloc, - bool is_retx, - bool schedule_sr_only, - srslog::basic_logger& logger, - ran_slice_id_t slice_id, +static alloc_result alloc_ul_ue(const slice_ue& u, + ue_pusch_allocator& pusch_alloc, + bool is_retx, + bool schedule_sr_only, + srslog::basic_logger& logger, + static_vector retx_harqs, std::optional ul_new_tx_max_nof_rbs_per_ue_per_slot = {}) { unsigned pending_newtx_bytes = 0; @@ -352,7 +325,7 @@ static alloc_result alloc_ul_ue(const slice_ue& u, if (is_retx) { // Get UL HARQ candidates. - const auto harq_candidates = get_ue_ul_harq_candidates(u, to_ue_cell_index(i), slice_id); + const auto harq_candidates = get_ue_harq_candidates(u.ue_index(), retx_harqs); if (harq_candidates.empty()) { // The conditions for a new PUSCH allocation for this UE were not met (e.g. lack of available HARQs). continue; @@ -379,6 +352,23 @@ static alloc_result alloc_ul_ue(const slice_ue& u, return {alloc_status::skip_ue}; } +/// \brief Fetches list of HARQs belonging to the slice and are pending retransmission. +template +static static_vector, MAX_NOF_HARQS> +get_slice_harq_pending_retx_candidates(ran_slice_id_t slice_id, harq_utils::harq_pending_retx_list_impl harq_list) +{ + using handle_type = std::conditional_t; + + static_vector harq_candidates; + for (handle_type h : harq_list) { + if (h.get_grant_params().slice_id == slice_id) { + harq_candidates.push_back(h); + } + } + + return harq_candidates; +} + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// scheduler_time_rr::scheduler_time_rr(const scheduler_ue_expert_config& expert_cfg_) : @@ -391,7 +381,8 @@ scheduler_time_rr::scheduler_time_rr(const scheduler_ue_expert_config& expert_cf void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc, const ue_resource_grid_view& res_grid, - dl_ran_slice_candidate& slice_candidate) + dl_ran_slice_candidate& slice_candidate, + dl_harq_pending_retx_list harq_pending_retx_list) { const slice_ue_repository& ues = slice_candidate.get_slice_ues(); const unsigned max_rbs = slice_candidate.remaining_rbs(); @@ -402,9 +393,12 @@ void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc, return; } + // Fetch HARQs pending retransmission for a slice. + auto retx_harqs = get_slice_harq_pending_retx_candidates(slice_id, harq_pending_retx_list); + // First, schedule UEs with re-transmissions. - auto retx_ue_function = [this, &res_grid, &pdsch_alloc, slice_id](const slice_ue& u) { - return alloc_dl_ue(u, res_grid, pdsch_alloc, true, logger, slice_id); + auto retx_ue_function = [this, &res_grid, &pdsch_alloc, retx_harqs](const slice_ue& u) { + return alloc_dl_ue(u, res_grid, pdsch_alloc, true, logger, retx_harqs); }; auto result = round_robin_apply(ues, next_dl_ue_index, retx_ue_function); next_dl_ue_index = result.first; @@ -417,8 +411,8 @@ void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc, if (dl_new_tx_max_nof_rbs_per_ue_per_slot > 0) { // Then, schedule UEs with new transmissions. auto drb_newtx_ue_function = - [this, &res_grid, &pdsch_alloc, dl_new_tx_max_nof_rbs_per_ue_per_slot, slice_id](const slice_ue& u) { - return alloc_dl_ue(u, res_grid, pdsch_alloc, false, logger, slice_id, dl_new_tx_max_nof_rbs_per_ue_per_slot); + [this, &res_grid, &pdsch_alloc, dl_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { + return alloc_dl_ue(u, res_grid, pdsch_alloc, false, logger, {}, dl_new_tx_max_nof_rbs_per_ue_per_slot); }; result = round_robin_apply(ues, next_dl_ue_index, drb_newtx_ue_function); next_dl_ue_index = result.first; @@ -427,7 +421,8 @@ void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc, void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc, const ue_resource_grid_view& res_grid, - ul_ran_slice_candidate& slice_candidate) + ul_ran_slice_candidate& slice_candidate, + ul_harq_pending_retx_list harq_pending_retx_list) { const slice_ue_repository& ues = slice_candidate.get_slice_ues(); const unsigned max_rbs = slice_candidate.remaining_rbs(); @@ -442,8 +437,8 @@ void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc, const unsigned ul_new_tx_max_nof_rbs_per_ue_per_slot = compute_max_nof_rbs_per_ue_per_slot(ues, false, res_grid, expert_cfg, max_rbs); // First, schedule UEs with pending SR. - auto sr_ue_function = [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot, slice_id](const slice_ue& u) { - return alloc_ul_ue(u, pusch_alloc, false, true, logger, slice_id, ul_new_tx_max_nof_rbs_per_ue_per_slot); + auto sr_ue_function = [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { + return alloc_ul_ue(u, pusch_alloc, false, true, logger, {}, ul_new_tx_max_nof_rbs_per_ue_per_slot); }; auto result = round_robin_apply(ues, next_ul_ue_index, sr_ue_function); next_ul_ue_index = result.first; @@ -451,9 +446,12 @@ void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc, return; } + // Fetch HARQs pending retransmission for a slice. + auto retx_harqs = get_slice_harq_pending_retx_candidates(slice_id, harq_pending_retx_list); + // Second, schedule UEs with re-transmissions. - auto data_retx_ue_function = [this, &pusch_alloc, slice_id](const slice_ue& u) { - return alloc_ul_ue(u, pusch_alloc, true, false, logger, slice_id); + auto data_retx_ue_function = [this, &pusch_alloc, retx_harqs](const slice_ue& u) { + return alloc_ul_ue(u, pusch_alloc, true, false, logger, retx_harqs); }; result = round_robin_apply(ues, next_ul_ue_index, data_retx_ue_function); next_ul_ue_index = result.first; @@ -463,10 +461,9 @@ void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc, // Then, schedule UEs with new transmissions. if (ul_new_tx_max_nof_rbs_per_ue_per_slot > 0) { - auto data_tx_ue_function = - [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot, slice_id](const slice_ue& u) { - return alloc_ul_ue(u, pusch_alloc, false, false, logger, slice_id, ul_new_tx_max_nof_rbs_per_ue_per_slot); - }; + auto data_tx_ue_function = [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { + return alloc_ul_ue(u, pusch_alloc, false, false, logger, {}, ul_new_tx_max_nof_rbs_per_ue_per_slot); + }; result = round_robin_apply(ues, next_ul_ue_index, data_tx_ue_function); next_ul_ue_index = result.first; } diff --git a/lib/scheduler/policy/scheduler_time_rr.h b/lib/scheduler/policy/scheduler_time_rr.h index e77fe866c7..ca177a59cb 100644 --- a/lib/scheduler/policy/scheduler_time_rr.h +++ b/lib/scheduler/policy/scheduler_time_rr.h @@ -20,11 +20,13 @@ class scheduler_time_rr : public scheduler_policy void dl_sched(ue_pdsch_allocator& pdsch_alloc, const ue_resource_grid_view& res_grid, - dl_ran_slice_candidate& slice_candidate) override; + dl_ran_slice_candidate& slice_candidate, + dl_harq_pending_retx_list harq_pending_retx_list) override; void ul_sched(ue_pusch_allocator& pusch_alloc, const ue_resource_grid_view& res_grid, - ul_ran_slice_candidate& slice_candidate) override; + ul_ran_slice_candidate& slice_candidate, + ul_harq_pending_retx_list harq_pending_retx_list) override; private: srslog::basic_logger& logger; diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp index f1401f5abc..52c5e20d3c 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp @@ -63,7 +63,8 @@ void ue_scheduler_impl::run_sched_strategy(slot_point slot_tx, du_cell_index_t c while (dl_slice_candidate.has_value()) { auto& policy = cells[cell_index]->slice_sched.get_policy(dl_slice_candidate->id()); dl_slice_ue_cell_grid_allocator slice_pdsch_alloc{ue_alloc, *dl_slice_candidate}; - policy.dl_sched(slice_pdsch_alloc, ue_res_grid_view, *dl_slice_candidate); + policy.dl_sched( + slice_pdsch_alloc, ue_res_grid_view, *dl_slice_candidate, cells[cell_index]->cell_harqs.pending_dl_retxs()); dl_slice_candidate = cells[cell_index]->slice_sched.get_next_dl_candidate(); } } @@ -72,7 +73,8 @@ void ue_scheduler_impl::run_sched_strategy(slot_point slot_tx, du_cell_index_t c while (ul_slice_candidate.has_value()) { auto& policy = cells[cell_index]->slice_sched.get_policy(ul_slice_candidate->id()); ul_slice_ue_cell_grid_allocator slice_pusch_alloc{ue_alloc, *ul_slice_candidate}; - policy.ul_sched(slice_pusch_alloc, ue_res_grid_view, *ul_slice_candidate); + policy.ul_sched( + slice_pusch_alloc, ue_res_grid_view, *ul_slice_candidate, cells[cell_index]->cell_harqs.pending_ul_retxs()); ul_slice_candidate = cells[cell_index]->slice_sched.get_next_ul_candidate(); } } diff --git a/tests/unittests/scheduler/policy/scheduler_policy_test.cpp b/tests/unittests/scheduler/policy/scheduler_policy_test.cpp index 51f523b7c3..a2827ed71f 100644 --- a/tests/unittests/scheduler/policy/scheduler_policy_test.cpp +++ b/tests/unittests/scheduler/policy/scheduler_policy_test.cpp @@ -80,14 +80,14 @@ class base_scheduler_policy_test while (dl_slice_candidate.has_value()) { auto& policy = slice_sched.get_policy(dl_slice_candidate->id()); dl_slice_ue_cell_grid_allocator slice_pdsch_alloc{grid_alloc, *dl_slice_candidate}; - policy.dl_sched(slice_pdsch_alloc, ue_res_grid, *dl_slice_candidate); + policy.dl_sched(slice_pdsch_alloc, ue_res_grid, *dl_slice_candidate, cell_harqs.pending_dl_retxs()); dl_slice_candidate = slice_sched.get_next_dl_candidate(); } auto ul_slice_candidate = slice_sched.get_next_ul_candidate(); while (ul_slice_candidate.has_value()) { auto& policy = slice_sched.get_policy(ul_slice_candidate->id()); ul_slice_ue_cell_grid_allocator slice_pusch_alloc{grid_alloc, *ul_slice_candidate}; - policy.ul_sched(slice_pusch_alloc, ue_res_grid, *ul_slice_candidate); + policy.ul_sched(slice_pusch_alloc, ue_res_grid, *ul_slice_candidate, cell_harqs.pending_ul_retxs()); ul_slice_candidate = slice_sched.get_next_ul_candidate(); } } From 7624d38da2d05f644a1f22ecf550539284221cd7 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Tue, 17 Sep 2024 11:24:27 +0200 Subject: [PATCH 084/174] sched: refactor RR scheduler to schedule all reTxes first based on received HARQs pending reTx list --- lib/scheduler/policy/scheduler_time_rr.cpp | 216 +++++++++------------ 1 file changed, 92 insertions(+), 124 deletions(-) diff --git a/lib/scheduler/policy/scheduler_time_rr.cpp b/lib/scheduler/policy/scheduler_time_rr.cpp index 2ae550b9c7..6df86995b6 100644 --- a/lib/scheduler/policy/scheduler_time_rr.cpp +++ b/lib/scheduler/policy/scheduler_time_rr.cpp @@ -130,11 +130,6 @@ static unsigned compute_max_nof_rbs_per_ue_per_slot(const slice_ue_repository& static bool can_allocate_dl_newtx(const slice_ue& ue_ref, ue_cell_index_t cell_index, srslog::basic_logger& logger) { - // If there are no pending new Tx bytes, return. - if (not ue_ref.has_pending_dl_newtx_bytes()) { - return false; - } - const ue_cell& ue_cc = ue_ref.get_cell(cell_index); if (not ue_cc.harqs.has_empty_dl_harqs()) { // No empty HARQs are available. Log this occurrence. @@ -158,31 +153,8 @@ static bool can_allocate_dl_newtx(const slice_ue& ue_ref, ue_cell_index_t cell_i return true; } -/// \brief Fetches list of HARQ candidates pending retransmission for a UE. -template -static static_vector, MAX_NOF_HARQS> -get_ue_harq_candidates(du_ue_index_t ue_index, - span> retx_harqs) -{ - using handle_type = std::conditional_t; - - static_vector harq_candidates; - for (handle_type h : retx_harqs) { - if (h.ue_index() == ue_index) { - harq_candidates.push_back(h); - } - } - - return harq_candidates; -} - static bool can_allocate_ul_newtx(const slice_ue& ue_ref, ue_cell_index_t cell_index, srslog::basic_logger& logger) { - // If there are no pending new Tx bytes, return. - if (ue_ref.pending_ul_newtx_bytes() == 0) { - return false; - } - const ue_cell& ue_cc = ue_ref.get_cell(cell_index); if (not ue_cc.harqs.has_empty_ul_harqs()) { // No empty HARQs are available. Log this occurrence. @@ -201,7 +173,6 @@ static bool can_allocate_ul_newtx(const slice_ue& ue_ref, ue_cell_index_t cell_i } return false; } - return true; } @@ -243,20 +214,51 @@ round_robin_apply(const slice_ue_repository& ue_db, du_ue_index_t next_ue_index, return std::make_pair(next_ue_index, alloc_status::success); } -/// Allocate UE PDSCH grant. -static alloc_result alloc_dl_ue(const slice_ue& u, - const ue_resource_grid_view& res_grid, - ue_pdsch_allocator& pdsch_alloc, - bool is_retx, - srslog::basic_logger& logger, - static_vector retx_harqs, - std::optional dl_new_tx_max_nof_rbs_per_ue_per_slot = {}) +/// Allocates UE PDSCH grant for retransmissions. +static alloc_result alloc_dl_retxs(const slice_ue_repository& ue_db, + const ue_resource_grid_view& res_grid, + ue_pdsch_allocator& pdsch_alloc, + ran_slice_id_t slice_id, + dl_harq_pending_retx_list harq_list) { - if (not is_retx) { - if (not u.has_pending_dl_newtx_bytes()) { - return {alloc_status::skip_ue}; + for (auto h : harq_list) { + if (h.get_grant_params().slice_id != slice_id or not ue_db.contains(h.ue_index())) { + continue; + } + const slice_ue& u = ue_db[h.ue_index()]; + // Prioritize PCell over SCells. + for (unsigned i = 0; i != u.nof_cells(); ++i) { + const ue_cell& ue_cc = u.get_cell(to_ue_cell_index(i)); + srsran_assert(ue_cc.is_active() and not ue_cc.is_in_fallback_mode(), + "policy scheduler called for UE={} in fallback", + ue_cc.ue_index); + + // [Implementation-defined] Skip UE if PDCCH is already allocated for this UE in this slot. + if (res_grid.has_ue_dl_pdcch(ue_cc.cell_index, u.crnti())) { + continue; + } + + ue_pdsch_grant grant{&u, ue_cc.cell_index, h.id()}; + const alloc_result result = pdsch_alloc.allocate_dl_grant(grant); + // If the allocation failed due to invalid parameters, we continue iteration. + if (result.status == alloc_status::skip_slot) { + return result; + } } } + return {alloc_status::success}; +} + +/// Allocate UE PDSCH grant for new transmissions. +static alloc_result alloc_dl_ue_newtx(const slice_ue& u, + const ue_resource_grid_view& res_grid, + ue_pdsch_allocator& pdsch_alloc, + srslog::basic_logger& logger, + std::optional dl_new_tx_max_nof_rbs_per_ue_per_slot = {}) +{ + if (not u.has_pending_dl_newtx_bytes()) { + return {alloc_status::skip_ue}; + } // Prioritize PCell over SCells. for (unsigned i = 0; i != u.nof_cells(); ++i) { @@ -271,19 +273,7 @@ static alloc_result alloc_dl_ue(const slice_ue& return {alloc_status::skip_ue}; } - if (is_retx) { - // Get DL HARQ candidates. - const auto harq_candidates = get_ue_harq_candidates(u.ue_index(), retx_harqs); - // Iterate through allocation parameter candidates. - for (dl_harq_process_handle h_dl : harq_candidates) { - ue_pdsch_grant grant{&u, ue_cc.cell_index, h_dl.id()}; - const alloc_result result = pdsch_alloc.allocate_dl_grant(grant); - // If the allocation failed due to invalid parameters, we continue iteration. - if (result.status != alloc_status::invalid_params) { - return result; - } - } - } else if (can_allocate_dl_newtx(u, to_ue_cell_index(i), logger)) { + if (can_allocate_dl_newtx(u, to_ue_cell_index(i), logger)) { ue_pdsch_grant grant{ &u, ue_cc.cell_index, INVALID_HARQ_ID, u.pending_dl_newtx_bytes(), dl_new_tx_max_nof_rbs_per_ue_per_slot}; const alloc_result result = pdsch_alloc.allocate_dl_grant(grant); @@ -296,25 +286,50 @@ static alloc_result alloc_dl_ue(const slice_ue& return {alloc_status::skip_ue}; } -/// Allocate UE PUSCH grant. -static alloc_result alloc_ul_ue(const slice_ue& u, - ue_pusch_allocator& pusch_alloc, - bool is_retx, - bool schedule_sr_only, - srslog::basic_logger& logger, - static_vector retx_harqs, - std::optional ul_new_tx_max_nof_rbs_per_ue_per_slot = {}) +/// Allocates UE PUSCH grant for retransmissions. +static alloc_result alloc_ul_retxs(const slice_ue_repository& ue_db, + ue_pusch_allocator& pusch_alloc, + ran_slice_id_t slice_id, + ul_harq_pending_retx_list harq_list) { - unsigned pending_newtx_bytes = 0; - if (not is_retx) { - if (schedule_sr_only and not u.has_pending_sr()) { - return {alloc_status::skip_ue}; + for (auto h : harq_list) { + if (h.get_grant_params().slice_id != slice_id or not ue_db.contains(h.ue_index())) { + continue; } - pending_newtx_bytes = u.pending_ul_newtx_bytes(); - if (pending_newtx_bytes == 0) { - return {alloc_status::skip_ue}; + const slice_ue& u = ue_db[h.ue_index()]; + // Prioritize PCell over SCells. + for (unsigned i = 0; i != u.nof_cells(); ++i) { + const ue_cell& ue_cc = u.get_cell(to_ue_cell_index(i)); + srsran_assert(ue_cc.is_active() and not ue_cc.is_in_fallback_mode(), + "policy scheduler called for UE={} in fallback", + ue_cc.ue_index); + + ue_pusch_grant grant{&u, ue_cc.cell_index, h.id()}; + const alloc_result result = pusch_alloc.allocate_ul_grant(grant); + // If the allocation failed due to invalid parameters, we continue iteration. + if (result.status == alloc_status::skip_slot) { + return result; + } } } + return {alloc_status::success}; +} + +/// Allocate UE PUSCH grant for new transmissions. +static alloc_result alloc_ul_ue_newtx(const slice_ue& u, + ue_pusch_allocator& pusch_alloc, + bool schedule_sr_only, + srslog::basic_logger& logger, + std::optional ul_new_tx_max_nof_rbs_per_ue_per_slot = {}) +{ + unsigned pending_newtx_bytes = 0; + if (schedule_sr_only and not u.has_pending_sr()) { + return {alloc_status::skip_ue}; + } + pending_newtx_bytes = u.pending_ul_newtx_bytes(); + if (pending_newtx_bytes == 0) { + return {alloc_status::skip_ue}; + } // Prioritize PCell over SCells. for (unsigned i = 0; i != u.nof_cells(); ++i) { @@ -323,23 +338,7 @@ static alloc_result alloc_ul_ue(const slice_ue& "policy scheduler called for UE={} in fallback", ue_cc.ue_index); - if (is_retx) { - // Get UL HARQ candidates. - const auto harq_candidates = get_ue_harq_candidates(u.ue_index(), retx_harqs); - if (harq_candidates.empty()) { - // The conditions for a new PUSCH allocation for this UE were not met (e.g. lack of available HARQs). - continue; - } - // Iterate through allocation parameter candidates. - for (ul_harq_process_handle h_ul : harq_candidates) { - ue_pusch_grant grant{&u, ue_cc.cell_index, h_ul.id()}; - const alloc_result result = pusch_alloc.allocate_ul_grant(grant); - // If the allocation failed due to invalid parameters, we continue iteration. - if (result.status != alloc_status::invalid_params) { - return result; - } - } - } else if (can_allocate_ul_newtx(u, to_ue_cell_index(i), logger)) { + if (can_allocate_ul_newtx(u, to_ue_cell_index(i), logger)) { ue_pusch_grant grant{ &u, ue_cc.cell_index, INVALID_HARQ_ID, pending_newtx_bytes, ul_new_tx_max_nof_rbs_per_ue_per_slot}; const alloc_result result = pusch_alloc.allocate_ul_grant(grant); @@ -352,23 +351,6 @@ static alloc_result alloc_ul_ue(const slice_ue& return {alloc_status::skip_ue}; } -/// \brief Fetches list of HARQs belonging to the slice and are pending retransmission. -template -static static_vector, MAX_NOF_HARQS> -get_slice_harq_pending_retx_candidates(ran_slice_id_t slice_id, harq_utils::harq_pending_retx_list_impl harq_list) -{ - using handle_type = std::conditional_t; - - static_vector harq_candidates; - for (handle_type h : harq_list) { - if (h.get_grant_params().slice_id == slice_id) { - harq_candidates.push_back(h); - } - } - - return harq_candidates; -} - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// scheduler_time_rr::scheduler_time_rr(const scheduler_ue_expert_config& expert_cfg_) : @@ -393,16 +375,9 @@ void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc, return; } - // Fetch HARQs pending retransmission for a slice. - auto retx_harqs = get_slice_harq_pending_retx_candidates(slice_id, harq_pending_retx_list); - // First, schedule UEs with re-transmissions. - auto retx_ue_function = [this, &res_grid, &pdsch_alloc, retx_harqs](const slice_ue& u) { - return alloc_dl_ue(u, res_grid, pdsch_alloc, true, logger, retx_harqs); - }; - auto result = round_robin_apply(ues, next_dl_ue_index, retx_ue_function); - next_dl_ue_index = result.first; - if (result.second == alloc_status::skip_slot) { + auto retx_result = alloc_dl_retxs(ues, res_grid, pdsch_alloc, slice_id, harq_pending_retx_list); + if (retx_result.status == alloc_status::skip_slot) { return; } @@ -412,9 +387,9 @@ void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc, // Then, schedule UEs with new transmissions. auto drb_newtx_ue_function = [this, &res_grid, &pdsch_alloc, dl_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { - return alloc_dl_ue(u, res_grid, pdsch_alloc, false, logger, {}, dl_new_tx_max_nof_rbs_per_ue_per_slot); + return alloc_dl_ue_newtx(u, res_grid, pdsch_alloc, logger, dl_new_tx_max_nof_rbs_per_ue_per_slot); }; - result = round_robin_apply(ues, next_dl_ue_index, drb_newtx_ue_function); + auto result = round_robin_apply(ues, next_dl_ue_index, drb_newtx_ue_function); next_dl_ue_index = result.first; } } @@ -438,7 +413,7 @@ void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc, compute_max_nof_rbs_per_ue_per_slot(ues, false, res_grid, expert_cfg, max_rbs); // First, schedule UEs with pending SR. auto sr_ue_function = [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { - return alloc_ul_ue(u, pusch_alloc, false, true, logger, {}, ul_new_tx_max_nof_rbs_per_ue_per_slot); + return alloc_ul_ue_newtx(u, pusch_alloc, true, logger, ul_new_tx_max_nof_rbs_per_ue_per_slot); }; auto result = round_robin_apply(ues, next_ul_ue_index, sr_ue_function); next_ul_ue_index = result.first; @@ -446,23 +421,16 @@ void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc, return; } - // Fetch HARQs pending retransmission for a slice. - auto retx_harqs = get_slice_harq_pending_retx_candidates(slice_id, harq_pending_retx_list); - // Second, schedule UEs with re-transmissions. - auto data_retx_ue_function = [this, &pusch_alloc, retx_harqs](const slice_ue& u) { - return alloc_ul_ue(u, pusch_alloc, true, false, logger, retx_harqs); - }; - result = round_robin_apply(ues, next_ul_ue_index, data_retx_ue_function); - next_ul_ue_index = result.first; - if (result.second == alloc_status::skip_slot) { + auto retx_result = alloc_ul_retxs(ues, pusch_alloc, slice_id, harq_pending_retx_list); + if (retx_result.status == alloc_status::skip_slot) { return; } // Then, schedule UEs with new transmissions. if (ul_new_tx_max_nof_rbs_per_ue_per_slot > 0) { auto data_tx_ue_function = [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { - return alloc_ul_ue(u, pusch_alloc, false, false, logger, {}, ul_new_tx_max_nof_rbs_per_ue_per_slot); + return alloc_ul_ue_newtx(u, pusch_alloc, false, logger, ul_new_tx_max_nof_rbs_per_ue_per_slot); }; result = round_robin_apply(ues, next_ul_ue_index, data_tx_ue_function); next_ul_ue_index = result.first; From d6d7b99b0c12b85b81073dc77c47e301eb9a3c8c Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Thu, 19 Sep 2024 16:56:59 +0200 Subject: [PATCH 085/174] sched: add comments to returned result during reTx scheduling in RR scheduler --- lib/scheduler/policy/scheduler_policy.h | 4 ++-- lib/scheduler/policy/scheduler_time_rr.cpp | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/scheduler/policy/scheduler_policy.h b/lib/scheduler/policy/scheduler_policy.h index 60209d82d2..9605bc0b86 100644 --- a/lib/scheduler/policy/scheduler_policy.h +++ b/lib/scheduler/policy/scheduler_policy.h @@ -109,7 +109,7 @@ class scheduler_policy /// gNB resource grid. /// \param[in] res_grid View of the current resource grid occupancy state for all gnb cells. /// \param[in] slice_candidate Slice candidate to be scheduled in the given slot. - /// \param[in] harq_pending_retx_list List of DL HARQs pending retransmission. + /// \param[in] harq_pending_retx_list List of DL HARQs pending retransmissions. virtual void dl_sched(ue_pdsch_allocator& pdsch_alloc, const ue_resource_grid_view& res_grid, dl_ran_slice_candidate& slice_candidate, @@ -120,7 +120,7 @@ class scheduler_policy /// gNB resource grid. /// \param[in] res_grid View of the current resource grid occupancy state for all gnb cells. /// \param[in] slice_candidate Slice candidate to be scheduled in the given slot. - /// \param[in] harq_pending_retx_list List of UL HARQs pending retransmission. + /// \param[in] harq_pending_retx_list List of UL HARQs pending retransmissions. virtual void ul_sched(ue_pusch_allocator& pusch_alloc, const ue_resource_grid_view& res_grid, ul_ran_slice_candidate& slice_candidate, diff --git a/lib/scheduler/policy/scheduler_time_rr.cpp b/lib/scheduler/policy/scheduler_time_rr.cpp index 6df86995b6..8d8f65bf8e 100644 --- a/lib/scheduler/policy/scheduler_time_rr.cpp +++ b/lib/scheduler/policy/scheduler_time_rr.cpp @@ -240,12 +240,18 @@ static alloc_result alloc_dl_retxs(const slice_ue_repository& ue_db, ue_pdsch_grant grant{&u, ue_cc.cell_index, h.id()}; const alloc_result result = pdsch_alloc.allocate_dl_grant(grant); - // If the allocation failed due to invalid parameters, we continue iteration. + // Continue iteration until skip slot indication is received. + // NOTE: Allocation status other than skip_slot can be ignored because allocation of reTxs is done from oldest + // HARQ pending to newest. Hence, other allocation status are redundant. if (result.status == alloc_status::skip_slot) { return result; } } } + // Return successful outcome in all other cases. + // Other cases: + // - No pending HARQs to allocate. + // - At the end of pending HARQs iteration. return {alloc_status::success}; } @@ -306,12 +312,18 @@ static alloc_result alloc_ul_retxs(const slice_ue_repository& ue_db, ue_pusch_grant grant{&u, ue_cc.cell_index, h.id()}; const alloc_result result = pusch_alloc.allocate_ul_grant(grant); - // If the allocation failed due to invalid parameters, we continue iteration. + // Continue iteration until skip slot indication is received. + // NOTE: Allocation status other than skip_slot can be ignored because allocation of reTxs is done from oldest + // HARQ pending to newest. Hence, other allocation status are redundant. if (result.status == alloc_status::skip_slot) { return result; } } } + // Return successful outcome in all other cases. + // Other cases: + // - No pending HARQs to allocate. + // - At the end of pending HARQs iteration. return {alloc_status::success}; } From ed1d1a2c2c810d39e0c885f009b02fa51f833e19 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 19 Sep 2024 13:51:19 +0200 Subject: [PATCH 086/174] e2: fix e2 setup request message with dummy content --- lib/e2/common/e2ap_asn1_helpers.h | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/e2/common/e2ap_asn1_helpers.h b/lib/e2/common/e2ap_asn1_helpers.h index 5da189bfcc..c54633c434 100644 --- a/lib/e2/common/e2ap_asn1_helpers.h +++ b/lib/e2/common/e2ap_asn1_helpers.h @@ -103,9 +103,29 @@ inline void fill_asn1_e2ap_setup_request(asn1::e2ap::e2setup_request_s& setup, list[0].load_info_obj(ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ITEM); e2node_component_cfg_addition_item_s& e2node_cfg_item = list[0].value().e2node_component_cfg_addition_item(); e2node_cfg_item.e2node_component_interface_type = e2node_component_interface_type_opts::ng; - e2node_cfg_item.e2node_component_id.set_e2node_component_interface_type_ng().amf_name.from_string("nginterf"); - e2node_cfg_item.e2node_component_cfg.e2node_component_request_part.from_string("72657170617274"); - e2node_cfg_item.e2node_component_cfg.e2node_component_resp_part.from_string("72657370617274"); + e2node_cfg_item.e2node_component_id.set_e2node_component_interface_type_ng().amf_name.from_string("test_amf_name"); + + uint8_t ngap_request[] = {0x00, 0x15, 0x00, 0x33, 0x00, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x08, 0x00, 0x00, 0xf1, + 0x10, 0x00, 0x00, 0x06, 0x6c, 0x00, 0x52, 0x40, 0x0a, 0x03, 0x80, 0x63, 0x75, 0x5f, + 0x63, 0x70, 0x5f, 0x30, 0x31, 0x00, 0x66, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x15, 0x40, 0x01, 0x60}; + + uint8_t ngap_resp[] = {0x20, 0x15, 0x00, 0x33, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x0f, 0x06, 0x00, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x61, 0x6d, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x60, + 0x00, 0x08, 0x00, 0x00, 0x00, 0xf1, 0x10, 0x02, 0x00, 0x40, 0x00, 0x56, 0x40, 0x01, + 0xff, 0x00, 0x50, 0x00, 0x08, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x08}; + byte_buffer request_buf = byte_buffer::create(ngap_request, ngap_request + sizeof(ngap_request)).value(); + byte_buffer resp_buf = byte_buffer::create(ngap_resp, ngap_resp + sizeof(ngap_resp)).value(); + + if (e2node_cfg_item.e2node_component_cfg.e2node_component_request_part.resize(request_buf.length())) { + std::copy(request_buf.begin(), + request_buf.end(), + e2node_cfg_item.e2node_component_cfg.e2node_component_request_part.begin()); + } + if (e2node_cfg_item.e2node_component_cfg.e2node_component_resp_part.resize(resp_buf.length())) { + std::copy( + resp_buf.begin(), resp_buf.end(), e2node_cfg_item.e2node_component_cfg.e2node_component_resp_part.begin()); + } } } // namespace srsran \ No newline at end of file From b2a81926b54446a76dc0cff6e38719b68f919b66 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Fri, 20 Sep 2024 10:41:52 +0200 Subject: [PATCH 087/174] mac: change log level from warning to info while logging discarded SDU for a removed UE --- lib/mac/mac_ul/pdu_rx_handler.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/mac/mac_ul/pdu_rx_handler.cpp b/lib/mac/mac_ul/pdu_rx_handler.cpp index 5cfa897249..af2a6e27c1 100644 --- a/lib/mac/mac_ul/pdu_rx_handler.cpp +++ b/lib/mac/mac_ul/pdu_rx_handler.cpp @@ -161,7 +161,10 @@ bool pdu_rx_handler::handle_rx_subpdus(const decoded_mac_rx_pdu& ctx) bool pdu_rx_handler::handle_sdu(const decoded_mac_rx_pdu& ctx, const mac_ul_sch_subpdu& sdu, mac_ul_ue_context* ue) { if (ue == nullptr) { - logger.warning("{}: Discarding SDU. Cause: Non-existent C-RNTI", create_prefix(ctx, sdu)); + // MAC PDUs can be processed after the UE has been removed, due to processing delays. + // TODO: Handle Msg3 SDUs that doesn't have UL-CCCH or C-RNTI CE. + srslog::log_channel& log_ch = ctx.ue_index == INVALID_DU_UE_INDEX ? logger.info : logger.warning; + log_ch("{}: Discarding SDU. Cause: Non-existent C-RNTI", create_prefix(ctx, sdu)); return false; } From e9fec554a8d3e4d6159a59679a9c85c47b0434a6 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 6 Sep 2024 17:26:18 +0200 Subject: [PATCH 088/174] du: functions to compute srs resource cell list Signed-off-by: Carlo Galiotto --- .../flexible_du/du_high/du_high_config.h | 6 +- .../du_high/du_high_config_translators.cpp | 6 +- include/srsran/du/du_cell_config.h | 21 +- .../ran_resource_management/CMakeLists.txt | 1 + .../srs_resource_generator.cpp | 78 +++++++ .../srs_resource_generator.h | 41 ++++ lib/du/du_update_config_helpers.cpp | 5 +- tests/unittests/du_manager/CMakeLists.txt | 5 + .../srs_resource_generator_test.cpp | 203 ++++++++++++++++++ 9 files changed, 358 insertions(+), 8 deletions(-) create mode 100644 lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp create mode 100644 lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.h create mode 100644 tests/unittests/du_manager/srs_resource_generator_test.cpp diff --git a/apps/units/flexible_du/du_high/du_high_config.h b/apps/units/flexible_du/du_high/du_high_config.h index 486b9d6cb0..10b30bc729 100644 --- a/apps/units/flexible_du/du_high/du_high_config.h +++ b/apps/units/flexible_du/du_high/du_high_config.h @@ -285,8 +285,10 @@ struct du_high_unit_pucch_config { }; struct du_high_unit_srs_config { - /// Enable Sound Reference Signals (SRS) for the UEs within this cell. - bool srs_enabled = false; + /// If set, enables periodic Sound Reference Signals (SRS) for the UEs within this cell. If not present, SRS are + /// aperiodic. + /// Values: {1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560}. + std::optional srs_period = std::nullopt; /// \brief Defines the maximum number of symbols dedicated to the cell SRS resources in a slot. Values: {1,...,6}. /// This is the space that the GNB reserves for all the cell SRS resources in the UL slots, not to be confused with /// the symbols per SRS resource configured in the UE dedicated configuration. diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index 187d387bfc..c5b41228f6 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -543,8 +543,10 @@ std::vector srsran::generate_du_cell_config(const du_hig // Parameters for SRS-Config. srs_du::srs_builder_params& du_srs_cfg = out_cell.srs_cfg; const du_high_unit_srs_config& user_srs_cfg = base_cell.srs_cfg; - du_srs_cfg.srs_enabled = user_srs_cfg.srs_enabled; - du_srs_cfg.max_nof_symbols = user_srs_cfg.max_nof_symbols_per_slot; + if (user_srs_cfg.srs_period.has_value()) { + du_srs_cfg.srs_period.emplace(static_cast(*user_srs_cfg.srs_period)); + } + du_srs_cfg.max_nof_symbols = user_srs_cfg.max_nof_symbols_per_slot; // Parameters for PUSCH-Config. if (not out_cell.ue_ded_serv_cell_cfg.ul_config.has_value()) { diff --git a/include/srsran/du/du_cell_config.h b/include/srsran/du/du_cell_config.h index f374d6fa4f..64b41c11fc 100644 --- a/include/srsran/du/du_cell_config.h +++ b/include/srsran/du/du_cell_config.h @@ -16,6 +16,7 @@ #include "srsran/ran/nr_cgi.h" #include "srsran/ran/pci.h" #include "srsran/ran/sib/system_info_config.h" +#include "srsran/ran/srs/srs_configuration.h" #include "srsran/ran/ssb_configuration.h" #include "srsran/ran/tdd/tdd_ul_dl_config.h" #include "srsran/scheduler/config/bwp_configuration.h" @@ -100,14 +101,30 @@ struct pucch_builder_params { }; struct srs_builder_params { - /// Enable Sound Reference Signals (SRS) for the UEs within this cell. - bool srs_enabled = false; + /// If present, defines the SRS period for SRS periodic resources, in slots. + /// When not present, the SRS resources are set as aperiodic. + std::optional srs_period = std::nullopt; /// Maximum number of symbols per UL slot dedicated for SRS resources. /// \remark In case of Sounding Reference Signals (SRS) being used, the number of symbols should be reduced so that /// the PUCCH resources do not overlap in symbols with the SRS resources. /// \remark The SRS resources are always placed at the end of the slot. /// \remark As per TS 38.211, Section 6.4.1.4.1, SRS resource can only be placed in the last 6 symbols of a slot. bounded_integer max_nof_symbols = 2U; + /// \c Transmission comb number , as per TS 38.211, Section 6.4.1.4.2, or TS 38.331, "SRS-Resource". + tx_comb_size tx_comb = tx_comb_size::n4; + /// Defines the number of symbols per SRS resource. + srs_nof_symbols nof_symbols = n1; + /// Defines the CS reuse factor for the SRS resources. + /// \remark With 2 or 4 antenna ports, different cyclic shifts are used by the different antennas. This parameter + /// defines how many UEs can be multiplexed in the same symbols and RBs by exploiting different cyclic shifts. + /// Values: {no_cyclic_shift, two, three, four, six} for 2 UL antenna ports. + /// Values: {no_cyclic_shift, three} for 4 UL antenna ports. + nof_cyclic_shifts cyclic_shift_reuse_factor = nof_cyclic_shifts::no_cyclic_shift; + /// Defines the reuse of the SRS sequence ID for different UEs within the same cell. + /// \remark The goal of the SRS sequence ID would be to reduce the inter-cell interference. However, if the cell is + /// not in a dense multi-cell environment, we can reuse different sequence ID for different cell UEs. + /// Values: {1, 2, 3, 5, 6, 10, 15, 30}. + unsigned sequence_id_reuse_factor = 1; }; /// Parameters that are used to initialize or build the \c PhysicalCellGroupConfig, TS 38.331. diff --git a/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt b/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt index a6e7ab5a81..88531936c6 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt +++ b/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt @@ -11,5 +11,6 @@ add_library(du_resource_manager du_pucch_resource_manager.cpp du_ran_resource_manager_impl.cpp pucch_resource_generator.cpp + srs_resource_generator.cpp ue_capability_manager.cpp) target_link_libraries(du_resource_manager du_manager_converters srsran_du_config_validators mac_configuration_helpers) diff --git a/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp b/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp new file mode 100644 index 0000000000..a350621784 --- /dev/null +++ b/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp @@ -0,0 +1,78 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srs_resource_generator.h" + +using namespace srsran; +using namespace srs_du; + +std::vector srsran::srs_du::generate_cell_srs_list(const du_cell_config& du_cell_cfg) +{ + std::vector srs_res_list; + // Compute the available TX comb offsets. \ref tx_comb_cyclic_shift, in \c srs_config::srs_resource::tx_comb_params. + std::vector tx_comb_offsets = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 + ? std::vector{0U, 1U} + : std::vector{0U, 1U, 2U, 3U}; + + // Compute the available Cyclic Shifts. + const unsigned max_cs = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 ? 8U : 12U; + const unsigned cs_step = max_cs / static_cast(du_cell_cfg.srs_cfg.cyclic_shift_reuse_factor); + std::vector cs_values; + for (unsigned cs = 0; cs < max_cs; cs += cs_step) { + cs_values.push_back(cs); + } + + // Compute the available Sequence IDs. + // NOTE: we only consider the number of orthogonal sequences that can be generated, as per TS 38.211, + // Section 6.4.1.4.2, which is 30. + constexpr unsigned max_seq_id_values = 30U; + const unsigned seq_id_step = max_seq_id_values / static_cast(du_cell_cfg.srs_cfg.sequence_id_reuse_factor); + std::vector seq_id_values; + for (unsigned seq_id = 0; seq_id < max_seq_id_values; seq_id += seq_id_step) { + seq_id_values.push_back(static_cast(du_cell_cfg.pci) + seq_id); + } + + // Find the first symbol within the UL slot (considering all options FDD, TDD pattern 1 and TDD pattern 2) where the + // SRS resource can be placed. + unsigned starting_sym = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.to_uint(); + if (du_cell_cfg.tdd_ul_dl_cfg_common.has_value()) { + const auto& tdd_cfg = du_cell_cfg.tdd_ul_dl_cfg_common.value(); + starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern1.nof_ul_symbols); + if (tdd_cfg.pattern2.has_value()) { + starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern2.value().nof_ul_symbols); + } + } + // The number of SRS symbols cannot be larger than 6. + starting_sym = std::max(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.max()); + + // We use the counter to define the cell resource ID. + unsigned srs_res_cnt = 0; + for (unsigned sym_start = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - static_cast(du_cell_cfg.srs_cfg.nof_symbols); + sym_start >= starting_sym; + sym_start -= static_cast(du_cell_cfg.srs_cfg.nof_symbols)) { + const ofdm_symbol_range srs_res_symbols{sym_start, + sym_start + static_cast(du_cell_cfg.srs_cfg.nof_symbols)}; + for (auto tx_comb_offset : tx_comb_offsets) { + for (auto cs : cs_values) { + for (auto seq_id : seq_id_values) { + du_srs_resource srs_res; + srs_res.cell_res_id = srs_res_cnt; + srs_res.tx_comb_offset = tx_comb_offset; + srs_res.symbols = srs_res_symbols; + srs_res.sequence_id = seq_id; + srs_res.cs = cs; + srs_res_list.push_back(srs_res); + ++srs_res_cnt; + } + } + } + } + return srs_res_list; +} diff --git a/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.h b/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.h new file mode 100644 index 0000000000..a65d447a26 --- /dev/null +++ b/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "du_ue_resource_config.h" + +namespace srsran::srs_du { + +/// Contains the parameters for the SRS resources of a cell. +struct du_srs_resource { + /// Id of the cell SRS resource. + unsigned cell_res_id; + /// Comb offset, as per \c transmissionComb, \c SRS-Resource, \c SRS-Config, TS 38.331. + bounded_integer tx_comb_offset; + /// OFDM symbol range where the SRS resource is placed. + ofdm_symbol_range symbols; + /// \c freqDomainPosition, as per \c SRS-Resource, \c SRS-Config, TS 38.331. + unsigned freq_dom_position = 0; + /// \c sequenceId, as per \c SRS-Resource, \c SRS-Config, TS 38.331. + unsigned sequence_id = 0; + /// Cyclic shift, as per \c transmissionComb, \c SRS-Resource, \c SRS-Config, TS 38.331. + unsigned cs = 0; +}; + +/// \brief Generates the list of orthogonal SRS resources available in a cell. +/// The resources of this cells are meant to be used by the UEs; the same resources can be reused by different UEs over +/// different slots. Note that this function does not allocate the resources to the UEs, it only creates the cell +/// resource list. +/// \param[in] du_cell_cfg Cell configuration parameters. +/// \return List of orthogonal SRS resources. +std::vector generate_cell_srs_list(const du_cell_config& du_cell_cfg); + +} // namespace srsran::srs_du diff --git a/lib/du/du_update_config_helpers.cpp b/lib/du/du_update_config_helpers.cpp index 2a75c11754..19e4152bac 100644 --- a/lib/du/du_update_config_helpers.cpp +++ b/lib/du/du_update_config_helpers.cpp @@ -126,6 +126,7 @@ srsran::config_helpers::compute_max_nof_pucch_symbols(const srs_du::srs_builder_ // [Implementation-defined] In the following, we compute the maximum number of PUCCH symbols that can be used in a // slot based on the PUCCH and SRS configurations. The maximum number of PUCCH symbols is computed so that PUCCH and // SRS resources occupy all symbols in a slot and in such a way that they do not overlap each other. - return user_srs_params.srs_enabled ? NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - user_srs_params.max_nof_symbols.to_uint() - : NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; + return user_srs_params.srs_period.has_value() + ? NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - user_srs_params.max_nof_symbols.to_uint() + : NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; } diff --git a/tests/unittests/du_manager/CMakeLists.txt b/tests/unittests/du_manager/CMakeLists.txt index 5a0ac6482a..3ed401eb4f 100644 --- a/tests/unittests/du_manager/CMakeLists.txt +++ b/tests/unittests/du_manager/CMakeLists.txt @@ -73,3 +73,8 @@ add_executable(pucch_resource_generator_test pucch_resource_generator_test.cpp) target_include_directories(pucch_resource_generator_test PRIVATE ${CMAKE_SOURCE_DIR}) target_link_libraries(pucch_resource_generator_test du_manager_test_helpers gtest gtest_main) gtest_discover_tests(pucch_resource_generator_test) + +add_executable(srs_resource_generator_test srs_resource_generator_test.cpp) +target_include_directories(srs_resource_generator_test PRIVATE ${CMAKE_SOURCE_DIR}) +target_link_libraries(srs_resource_generator_test du_manager_test_helpers gtest gtest_main) +gtest_discover_tests(srs_resource_generator_test) \ No newline at end of file diff --git a/tests/unittests/du_manager/srs_resource_generator_test.cpp b/tests/unittests/du_manager/srs_resource_generator_test.cpp new file mode 100644 index 0000000000..bc34c9b371 --- /dev/null +++ b/tests/unittests/du_manager/srs_resource_generator_test.cpp @@ -0,0 +1,203 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.h" +#include "srsran/du/du_cell_config_helpers.h" +#include "srsran/support/test_utils.h" +#include + +using namespace srsran; +using namespace srs_du; + +namespace { +struct srs_cfg_builder_params { + std::optional nof_ul_symbols = std::nullopt; + bounded_integer max_nof_symbols = 2U; + tx_comb_size tx_comb = tx_comb_size::n4; + srs_nof_symbols nof_symbols = n1; + nof_cyclic_shifts cyclic_shift_reuse_factor = nof_cyclic_shifts::no_cyclic_shift; + unsigned sequence_id_reuse_factor = 1; +}; +} // namespace + +class test_srs_res_list_builder : public ::testing::TestWithParam +{ +protected: + test_srs_res_list_builder() + { + // Validate the input parameters + if (GetParam().tx_comb == tx_comb_size::n2) { + /// Cyclic shift that we can use with the n2 TX comb size. + const std::array css{ + nof_cyclic_shifts::no_cyclic_shift, nof_cyclic_shifts::two, nof_cyclic_shifts::four}; + srsran_assert(std::find(css.cbegin(), css.cend(), GetParam().cyclic_shift_reuse_factor) != css.end(), + "Cyclic shift reuse factor set is not compatible with the TX comb size"); + } + srsran_assert(GetParam().max_nof_symbols.to_uint() >= static_cast(GetParam().nof_symbols), + "The number of symbols per SRS resource cannot be larger than the maximum number of symbols for the " + "entire SRS area"); + + // Default PCI. + du_cell_cfg.pci = 1U; + + // In the TDD configuration, the only parameter that matters is the number of UL symbols. + if (GetParam().nof_ul_symbols.has_value()) { + tdd_ul_dl_config_common tdd_cfg = {.ref_scs = srsran::subcarrier_spacing::kHz30, + .pattern1 = tdd_ul_dl_pattern{10U, 6, 0, 3, GetParam().nof_ul_symbols.value()}, + .pattern2 = std::nullopt}; + du_cell_cfg.tdd_ul_dl_cfg_common.emplace(tdd_cfg); + } + + auto& srs_cfg = du_cell_cfg.srs_cfg; + srs_cfg.srs_period.emplace(srs_periodicity::sl20); + srs_cfg.tx_comb = GetParam().tx_comb; + srs_cfg.nof_symbols = GetParam().nof_symbols; + srs_cfg.cyclic_shift_reuse_factor = GetParam().cyclic_shift_reuse_factor; + srs_cfg.sequence_id_reuse_factor = GetParam().sequence_id_reuse_factor; + srs_cfg.max_nof_symbols = GetParam().max_nof_symbols; + + nof_symbols_srs_area = du_cell_cfg.srs_cfg.max_nof_symbols.to_uint(); + if (du_cell_cfg.tdd_ul_dl_cfg_common.has_value()) { + const auto& tdd_cfg = du_cell_cfg.tdd_ul_dl_cfg_common.value(); + nof_symbols_srs_area = std::max(nof_symbols_srs_area, tdd_cfg.pattern1.nof_ul_symbols); + if (tdd_cfg.pattern2.has_value()) { + nof_symbols_srs_area = std::max(nof_symbols_srs_area, tdd_cfg.pattern2.value().nof_ul_symbols); + } + // The number of SRS symbols cannot be larger than 6. + nof_symbols_srs_area = std::min(nof_symbols_srs_area, 6U); + } + nof_symbol_intervals = nof_symbols_srs_area / static_cast(du_cell_cfg.srs_cfg.nof_symbols); + }; + + unsigned compute_expected_srs_list_size() const + { + return nof_symbol_intervals * static_cast(du_cell_cfg.srs_cfg.tx_comb) * + static_cast(du_cell_cfg.srs_cfg.cyclic_shift_reuse_factor) * + static_cast(du_cell_cfg.srs_cfg.sequence_id_reuse_factor); + } + + bool check_res_list_elements(span srs_res_list) const + { + const unsigned max_cs = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 ? 8U : 12U; + for (const auto& srs_res : srs_res_list) { + if (srs_res.tx_comb_offset >= static_cast(du_cell_cfg.srs_cfg.tx_comb)) { + return false; + } + if (srs_res.cs >= max_cs) { + return false; + } + } + + // Count the number of SRS resources for each TX comb offset. + const std::vector tx_comb_offsets = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 + ? std::vector{0U, 1U} + : std::vector{0U, 1U, 2U, 3U}; + for (const auto& comb_offset : tx_comb_offsets) { + const auto nof_elements = static_cast( + std::count_if(srs_res_list.begin(), srs_res_list.end(), [comb_offset](const du_srs_resource& res) { + return res.tx_comb_offset.to_uint() == comb_offset; + })); + + if (nof_elements != compute_expected_srs_list_size() / tx_comb_offsets.size()) { + return false; + } + } + + // Count the number of SRS resources for each cyclic shift value. + const unsigned cs_step = max_cs / static_cast(du_cell_cfg.srs_cfg.cyclic_shift_reuse_factor); + std::vector cs_values; + for (unsigned cs = 0; cs < max_cs; cs += cs_step) { + cs_values.push_back(cs); + } + for (auto cs : cs_values) { + const auto nof_elements = static_cast(std::count_if( + srs_res_list.begin(), srs_res_list.end(), [cs](const du_srs_resource& res) { return res.cs == cs; })); + if (nof_elements != compute_expected_srs_list_size() / cs_values.size()) { + return false; + } + } + + // Count the number of SRS resources for each Sequence Index. + constexpr unsigned max_seq_id_values = 30U; + const unsigned seq_id_step = + max_seq_id_values / static_cast(du_cell_cfg.srs_cfg.sequence_id_reuse_factor); + std::vector seq_id_values; + for (unsigned seq_id = 0; seq_id < max_seq_id_values; seq_id += seq_id_step) { + seq_id_values.push_back(static_cast(du_cell_cfg.pci) + seq_id); + } + for (auto seq_id : seq_id_values) { + const auto nof_elements = static_cast( + std::count_if(srs_res_list.begin(), srs_res_list.end(), [seq_id](const du_srs_resource& res) { + return res.sequence_id == seq_id; + })); + if (nof_elements != compute_expected_srs_list_size() / seq_id_values.size()) { + return false; + } + } + + // Count the number of SRS resources for each symbol interval. + for (unsigned sym_start = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - static_cast(du_cell_cfg.srs_cfg.nof_symbols); + sym_start >= NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - nof_symbols_srs_area; + sym_start -= static_cast(du_cell_cfg.srs_cfg.nof_symbols)) { + const auto nof_elements = static_cast(std::count_if( + srs_res_list.begin(), + srs_res_list.end(), + [sym_start, srs_sym_length = du_cell_cfg.srs_cfg.nof_symbols](const du_srs_resource& res) { + return res.symbols == ofdm_symbol_range{sym_start, sym_start + static_cast(srs_sym_length)}; + })); + if (nof_elements != compute_expected_srs_list_size() / nof_symbol_intervals) { + return false; + } + } + + return true; + } + + du_cell_config du_cell_cfg; + // Values that are used to check the SRS list. + // Number of symbols that are reserved for SRS. + unsigned nof_symbols_srs_area = 0; + unsigned nof_symbol_intervals = 0; +}; + +TEST_P(test_srs_res_list_builder, test_whether_list_is_generated_and_has_correct_size) +{ + auto srs_res_list = generate_cell_srs_list(du_cell_cfg); + ASSERT_FALSE(srs_res_list.empty()); + ASSERT_EQ(compute_expected_srs_list_size(), srs_res_list.size()); + ASSERT_TRUE(check_res_list_elements(srs_res_list)); +} + +INSTANTIATE_TEST_SUITE_P( + test_both_fdd_and_tdd_srs_res_list_builder, + test_srs_res_list_builder, + // clang-format off + ::testing::Values( + // FDD. + srs_cfg_builder_params{std::nullopt, 2, tx_comb_size::n4, srs_nof_symbols::n1, nof_cyclic_shifts::no_cyclic_shift,1}, + srs_cfg_builder_params{std::nullopt, 2, tx_comb_size::n4, srs_nof_symbols::n2, nof_cyclic_shifts::no_cyclic_shift, 1}, + srs_cfg_builder_params{std::nullopt, 3, tx_comb_size::n2, srs_nof_symbols::n1, nof_cyclic_shifts::two, 1}, + srs_cfg_builder_params{std::nullopt, 6, tx_comb_size::n2, srs_nof_symbols::n1, nof_cyclic_shifts::no_cyclic_shift, 6}, + srs_cfg_builder_params{std::nullopt, 6, tx_comb_size::n4, srs_nof_symbols::n2, nof_cyclic_shifts::twelve, 5}, + srs_cfg_builder_params{std::nullopt, 4, tx_comb_size::n4, srs_nof_symbols::n2, nof_cyclic_shifts::six, 15}, + srs_cfg_builder_params{std::nullopt, 4, tx_comb_size::n4, srs_nof_symbols::n4, nof_cyclic_shifts::six, 15}, + srs_cfg_builder_params{std::nullopt, 6, tx_comb_size::n4, srs_nof_symbols::n1, nof_cyclic_shifts::twelve, 30}, + // TDD. + srs_cfg_builder_params{3, 2, tx_comb_size::n4, srs_nof_symbols::n1, nof_cyclic_shifts::no_cyclic_shift,1}, + srs_cfg_builder_params{5, 2, tx_comb_size::n4, srs_nof_symbols::n1, nof_cyclic_shifts::no_cyclic_shift,1}, + srs_cfg_builder_params{4, 2, tx_comb_size::n4, srs_nof_symbols::n2, nof_cyclic_shifts::no_cyclic_shift, 1}, + srs_cfg_builder_params{5, 2, tx_comb_size::n4, srs_nof_symbols::n2, nof_cyclic_shifts::no_cyclic_shift, 1}, + srs_cfg_builder_params{2, 3, tx_comb_size::n2, srs_nof_symbols::n1, nof_cyclic_shifts::two, 1}, + srs_cfg_builder_params{3, 6, tx_comb_size::n2, srs_nof_symbols::n1, nof_cyclic_shifts::no_cyclic_shift, 6}, + srs_cfg_builder_params{2, 4, tx_comb_size::n4, srs_nof_symbols::n4, nof_cyclic_shifts::six, 15}, + srs_cfg_builder_params{6, 4, tx_comb_size::n4, srs_nof_symbols::n2, nof_cyclic_shifts::twelve, 6} + ) + // clang-format on +); From b23e7d050a96a4fe7797ec6d1164ec52f6071827 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Tue, 17 Sep 2024 12:51:13 +0200 Subject: [PATCH 089/174] du: improve comment clarity in srs res generator Signed-off-by: Carlo Galiotto --- .../srs_resource_generator.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp b/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp index a350621784..31eec960b5 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/srs_resource_generator.cpp @@ -16,12 +16,14 @@ using namespace srs_du; std::vector srsran::srs_du::generate_cell_srs_list(const du_cell_config& du_cell_cfg) { std::vector srs_res_list; - // Compute the available TX comb offsets. \ref tx_comb_cyclic_shift, in \c srs_config::srs_resource::tx_comb_params. + // TX comb offsets values, depending on the TX comb value, as per TS 38.331, \c transmissionComb, \c SRS-Resource, + // \c SRS-Config. std::vector tx_comb_offsets = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 ? std::vector{0U, 1U} : std::vector{0U, 1U, 2U, 3U}; - // Compute the available Cyclic Shifts. + // Cyclic Shifts values, depending on the TX comb value, as per TS 38.331, \c cyclicShift, \c SRS-Resource, + // \c SRS-Config. const unsigned max_cs = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 ? 8U : 12U; const unsigned cs_step = max_cs / static_cast(du_cell_cfg.srs_cfg.cyclic_shift_reuse_factor); std::vector cs_values; @@ -39,8 +41,11 @@ std::vector srsran::srs_du::generate_cell_srs_list(const du_cel seq_id_values.push_back(static_cast(du_cell_cfg.pci) + seq_id); } - // Find the first symbol within the UL slot (considering all options FDD, TDD pattern 1 and TDD pattern 2) where the - // SRS resource can be placed. + // At this point, the SRS resource is not assigned to a given slot, and we need to consider all possible UL symbols + // where the SRS can be placed. The viable symbols for SRS are defined by the user configuration, through \c + // max_nof_symbols for fully-UL slots, or by the number of UL symbols for partially-UL slots. We take the min of + // these 2 values as starting symbol, and we cap it to the 6th last symbol, which is sey by the standard, as per + // TS 38.211, Section 6.4.1.4.1. unsigned starting_sym = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.to_uint(); if (du_cell_cfg.tdd_ul_dl_cfg_common.has_value()) { const auto& tdd_cfg = du_cell_cfg.tdd_ul_dl_cfg_common.value(); @@ -49,7 +54,8 @@ std::vector srsran::srs_du::generate_cell_srs_list(const du_cel starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern2.value().nof_ul_symbols); } } - // The number of SRS symbols cannot be larger than 6. + // Cap the starting symbol to the 6th last symbol of the slot (\c du_cell_cfg.srs_cfg.max_nof_symbols.max()), as per + // TS 38.211, Section 6.4.1.4.1. starting_sym = std::max(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.max()); // We use the counter to define the cell resource ID. From 3458cf30321db24dfc1425206982a96b46b8cd88 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 16 Sep 2024 16:19:25 +0200 Subject: [PATCH 090/174] cu_cp: remove du processor to rrc du adapter --- lib/cu_cp/adapters/du_processor_adapters.h | 41 -------------------- lib/cu_cp/du_processor/du_processor.h | 24 ------------ lib/cu_cp/du_processor/du_processor_impl.cpp | 13 +++---- lib/cu_cp/du_processor/du_processor_impl.h | 3 -- tests/unittests/cu_cp/test_helpers.h | 23 ----------- 5 files changed, 6 insertions(+), 98 deletions(-) diff --git a/lib/cu_cp/adapters/du_processor_adapters.h b/lib/cu_cp/adapters/du_processor_adapters.h index c9e55161cb..6ee43937df 100644 --- a/lib/cu_cp/adapters/du_processor_adapters.h +++ b/lib/cu_cp/adapters/du_processor_adapters.h @@ -99,47 +99,6 @@ class du_processor_f1ap_ue_context_adapter : public du_processor_f1ap_ue_context f1ap_ue_context_manager* handler = nullptr; }; -// Adapter between DU processor and RRC DU -class du_processor_rrc_du_adapter : public du_processor_rrc_du_ue_notifier -{ -public: - du_processor_rrc_du_adapter() = default; - - void connect_rrc_du(rrc_du_cell_manager& rrc_du_cell_handler_, rrc_du_ue_repository& rrc_du_handler_) - { - rrc_du_cell_handler = &rrc_du_cell_handler_; - rrc_du_handler = &rrc_du_handler_; - } - - bool on_new_served_cell_list(const std::vector& served_cell_list) override - { - srsran_assert(rrc_du_cell_handler != nullptr, "RRC DU cell handler must not be nullptr"); - return rrc_du_cell_handler->handle_served_cell_list(served_cell_list); - } - - byte_buffer on_rrc_reject_required() override - { - srsran_assert(rrc_du_handler != nullptr, "RRC DU UE handler must not be nullptr"); - return rrc_du_handler->get_rrc_reject(); - } - - rrc_ue_interface* on_ue_creation_request(const rrc_ue_creation_message& msg) override - { - srsran_assert(rrc_du_handler != nullptr, "RRC DU UE handler must not be nullptr"); - return rrc_du_handler->add_ue(msg); - } - - void on_release_ues() override - { - srsran_assert(rrc_du_handler != nullptr, "RRC DU UE handler must not be nullptr"); - return rrc_du_handler->release_ues(); - } - -private: - rrc_du_cell_manager* rrc_du_cell_handler = nullptr; - rrc_du_ue_repository* rrc_du_handler = nullptr; -}; - // Adapter between DU processor and RRC UE class du_processor_rrc_ue_adapter : public du_processor_rrc_ue_notifier { diff --git a/lib/cu_cp/du_processor/du_processor.h b/lib/cu_cp/du_processor/du_processor.h index ade2c889c7..20fe67ba1d 100644 --- a/lib/cu_cp/du_processor/du_processor.h +++ b/lib/cu_cp/du_processor/du_processor.h @@ -74,30 +74,6 @@ class du_processor_cell_info_interface virtual const du_configuration_context* get_context() const = 0; }; -/// Interface to notify RRC DU about UE management procedures. -class du_processor_rrc_du_ue_notifier -{ -public: - virtual ~du_processor_rrc_du_ue_notifier() = default; - - /// \brief Notify RRC DU about served cells. - /// \param[in] served_cell_list The list of served cells. - /// \return Returns true on success, false otherwise. - virtual bool on_new_served_cell_list(const std::vector& served_cell_list) = 0; - - /// \brief Notify RRC DU about a required RRCReject. - /// \return Returns a RRC Container containing the RRCReject. - virtual byte_buffer on_rrc_reject_required() = 0; - - /// \brief Notify RRC DU to create a UE. - /// \param[in] msg The UE creation message. - /// \return Returns a handle to the created UE. - virtual rrc_ue_interface* on_ue_creation_request(const rrc_ue_creation_message& msg) = 0; - - /// Send RRC Release to all UEs connected to this DU. - virtual void on_release_ues() = 0; -}; - /// Interface to notify an RRC UE about control and srb messages. class du_processor_rrc_ue_notifier { diff --git a/lib/cu_cp/du_processor/du_processor_impl.cpp b/lib/cu_cp/du_processor/du_processor_impl.cpp index 29e07f6434..44de44b9cb 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.cpp +++ b/lib/cu_cp/du_processor/du_processor_impl.cpp @@ -96,7 +96,6 @@ du_processor_impl::du_processor_impl(du_processor_config_t du_proc // create RRC rrc_du_creation_message du_creation_req{create_rrc_config(cfg.cu_cp_cfg), rrc_du_cu_cp_notifier}; rrc = create_rrc_du(du_creation_req); - rrc_du_adapter.connect_rrc_du(rrc->get_rrc_du_cell_manager(), rrc->get_rrc_du_ue_repository()); } du_setup_result du_processor_impl::handle_du_setup_request(const du_setup_request& request) @@ -119,7 +118,7 @@ du_setup_result du_processor_impl::handle_du_setup_request(const du_setup_reques // Forward serving cell list to RRC DU // TODO: How to handle missing optional freq and timing in meas timing config? - if (!rrc_du_adapter.on_new_served_cell_list(request.gnb_du_served_cells_list)) { + if (!rrc->handle_served_cell_list(request.gnb_du_served_cells_list)) { res.result = du_setup_result::rejected{f1ap_cause_transport_t::unspecified, "Could not establish served cell list in RRC"}; return res; @@ -168,7 +167,7 @@ bool du_processor_impl::create_rrc_ue(cu_cp_ue& ue, rrc_ue_create_msg.cu_cp_ue_notifier = &ue.get_rrc_ue_cu_cp_ue_notifier(); rrc_ue_create_msg.du_to_cu_container = std::move(du_to_cu_rrc_container); rrc_ue_create_msg.rrc_context = std::move(rrc_context); - auto* rrc_ue = rrc_du_adapter.on_ue_creation_request(std::move(rrc_ue_create_msg)); + auto* rrc_ue = rrc->add_ue(std::move(rrc_ue_create_msg)); if (rrc_ue == nullptr) { logger.warning("Could not create RRC UE"); return false; @@ -195,7 +194,7 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c if (pcell == nullptr) { logger.warning("ue={} c-rnti={}: Could not find cell with NCI={}", req.ue_index, req.c_rnti, req.cgi.nci); // Return the RRCReject container - return make_unexpected(rrc_du_adapter.on_rrc_reject_required()); + return make_unexpected(rrc->get_rrc_reject()); } const pci_t pci = pcell->pci; @@ -208,7 +207,7 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c cfg.du_index, req.cgi.plmn_id, cfg.du_cfg_hdlr->get_context().id, pci, req.c_rnti, pcell->cell_index); if (ue_index == ue_index_t::invalid) { logger.warning("CU-CP UE creation failed"); - return make_unexpected(rrc_du_adapter.on_rrc_reject_required()); + return make_unexpected(rrc->get_rrc_reject()); } ue = ue_mng.find_ue(ue_index); @@ -219,7 +218,7 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c if (ue == nullptr) { logger.warning("ue={}: Could not create UE context", ue_index); // A UE with the same PCI and RNTI already exists, so we don't remove it and only reject the new UE. - return make_unexpected(rrc_du_adapter.on_rrc_reject_required()); + return make_unexpected(rrc->get_rrc_reject()); } } @@ -229,7 +228,7 @@ du_processor_impl::handle_ue_rrc_context_creation_request(const ue_rrc_context_c // Remove the UE from the UE manager ue_mng.remove_ue(ue_index); // Return the RRCReject container - return make_unexpected(rrc_du_adapter.on_rrc_reject_required()); + return make_unexpected(rrc->get_rrc_reject()); } rrc_ue_interface* rrc_ue = rrc->find_ue(ue_index); f1ap_rrc_ue_adapters[ue_index] = {}; diff --git a/lib/cu_cp/du_processor/du_processor_impl.h b/lib/cu_cp/du_processor/du_processor_impl.h index 2b5c563783..4b4a6de67f 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.h +++ b/lib/cu_cp/du_processor/du_processor_impl.h @@ -105,9 +105,6 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public // RRC UE to F1AP adapters std::unordered_map rrc_ue_f1ap_adapters; - // DU processor to RRC DU adapter - du_processor_rrc_du_adapter rrc_du_adapter; - // DU processor to RRC UE adapters std::unordered_map rrc_ue_adapters; diff --git a/tests/unittests/cu_cp/test_helpers.h b/tests/unittests/cu_cp/test_helpers.h index 9d48fd4330..02e31e5004 100644 --- a/tests/unittests/cu_cp/test_helpers.h +++ b/tests/unittests/cu_cp/test_helpers.h @@ -618,29 +618,6 @@ struct dummy_du_processor_rrc_ue_notifier : public du_processor_rrc_ue_notifier static_vector srb_vec; }; -struct dummy_du_processor_rrc_du_ue_notifier : public du_processor_rrc_du_ue_notifier { -public: - dummy_du_processor_rrc_du_ue_notifier() = default; - - bool on_new_served_cell_list(const std::vector& served_cell_list) override - { - logger.info("Received a served cell list"); - return true; - } - - rrc_ue_interface* on_ue_creation_request(const rrc_ue_creation_message& msg) override - { - logger.info("Received a UE creation request"); - return nullptr; - } - - /// Send RRC Release to all UEs connected to this DU. - void on_release_ues() override { logger.info("Releasing all UEs"); } - -private: - srslog::basic_logger& logger = srslog::fetch_basic_logger("TEST"); -}; - struct dummy_cu_up_processor_cu_up_management_notifier : public cu_up_processor_cu_up_management_notifier { public: dummy_cu_up_processor_cu_up_management_notifier() = default; From 6dc50298ad00efae1208c128744af3eec2965634 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 16 Sep 2024 17:53:35 +0200 Subject: [PATCH 091/174] cu_cp,rrc: remove du processor to rrc ue adapter --- include/srsran/rrc/rrc_ue.h | 2 +- lib/cu_cp/adapters/du_processor_adapters.h | 92 -------- lib/cu_cp/cu_cp_impl.cpp | 17 +- lib/cu_cp/du_processor/du_processor.h | 63 ------ lib/cu_cp/du_processor/du_processor_impl.cpp | 5 - lib/cu_cp/du_processor/du_processor_impl.h | 3 - .../handover_reconfiguration_routine.cpp | 2 +- .../inter_cu_handover_target_routine.cpp | 7 +- .../mobility/inter_du_handover_routine.cpp | 8 +- ..._session_resource_modification_routine.cpp | 8 +- ...du_session_resource_modification_routine.h | 16 +- .../pdu_session_resource_release_routine.cpp | 8 +- .../pdu_session_resource_release_routine.h | 16 +- .../pdu_session_resource_setup_routine.cpp | 10 +- .../pdu_session_resource_setup_routine.h | 16 +- ...blishment_context_modification_routine.cpp | 6 +- ...tablishment_context_modification_routine.h | 20 +- .../routines/ue_context_release_routine.cpp | 5 +- lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp | 14 -- lib/cu_cp/ue_manager/cu_cp_ue_impl.h | 10 +- .../handover_reconfiguration_routine_test.cpp | 204 ++++++++++++++++-- tests/unittests/cu_cp/test_helpers.h | 103 --------- .../ue_manager/ue_manager_test_helpers.h | 3 +- 23 files changed, 252 insertions(+), 386 deletions(-) diff --git a/include/srsran/rrc/rrc_ue.h b/include/srsran/rrc/rrc_ue.h index faee7428b6..259403f010 100644 --- a/include/srsran/rrc/rrc_ue.h +++ b/include/srsran/rrc/rrc_ue.h @@ -264,7 +264,7 @@ class rrc_ue_control_message_handler /// \brief Get the RRC measurement config for the current serving cell of the UE. /// \params[in] current_meas_config The current meas config of the UE (if applicable). /// \return The measurement config, if present. - virtual std::optional generate_meas_config(std::optional current_meas_config) = 0; + virtual std::optional generate_meas_config(std::optional current_meas_config = {}) = 0; /// \brief Handle the handover command RRC PDU. /// \param[in] cmd The handover command RRC PDU. diff --git a/lib/cu_cp/adapters/du_processor_adapters.h b/lib/cu_cp/adapters/du_processor_adapters.h index 6ee43937df..0df55520b1 100644 --- a/lib/cu_cp/adapters/du_processor_adapters.h +++ b/lib/cu_cp/adapters/du_processor_adapters.h @@ -99,98 +99,6 @@ class du_processor_f1ap_ue_context_adapter : public du_processor_f1ap_ue_context f1ap_ue_context_manager* handler = nullptr; }; -// Adapter between DU processor and RRC UE -class du_processor_rrc_ue_adapter : public du_processor_rrc_ue_notifier -{ -public: - du_processor_rrc_ue_adapter() = default; - - void connect_rrc_ue(rrc_ue_control_message_handler& rrc_ue_handler_) { rrc_ue_handler = &rrc_ue_handler_; } - - async_task on_ue_capability_transfer_request(const rrc_ue_capability_transfer_request& msg) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->handle_rrc_ue_capability_transfer_request(msg); - } - - async_task on_rrc_reconfiguration_request(const rrc_reconfiguration_procedure_request& msg) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->handle_rrc_reconfiguration_request(msg); - } - - byte_buffer get_packed_ue_capability_rat_container_list() override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->get_packed_ue_capability_rat_container_list(); - } - - rrc_ue_handover_reconfiguration_context - get_rrc_ue_handover_reconfiguration_context(const rrc_reconfiguration_procedure_request& request) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->get_rrc_ue_handover_reconfiguration_context(request); - } - - async_task on_handover_reconfiguration_complete_expected(uint8_t transaction_id) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->handle_handover_reconfiguration_complete_expected(transaction_id); - } - - rrc_ue_release_context get_rrc_ue_release_context(bool requires_rrc_msg) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->get_rrc_ue_release_context(requires_rrc_msg); - } - - rrc_ue_transfer_context get_transfer_context() override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->get_transfer_context(); - } - - std::optional generate_meas_config(std::optional current_meas_config = {}) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->generate_meas_config(current_meas_config); - } - - byte_buffer get_packed_handover_preparation_message() override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->get_packed_handover_preparation_message(); - } - - byte_buffer on_new_rrc_handover_command(byte_buffer cmd) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->handle_rrc_handover_command(std::move(cmd)); - } - - byte_buffer on_rrc_handover_command_required(const rrc_reconfiguration_procedure_request& request, - unsigned transaction_id) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->get_rrc_handover_command(request, transaction_id); - } - - void create_srb(const srb_creation_message& msg) override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->create_srb(msg); - } - - static_vector get_srbs() override - { - srsran_assert(rrc_ue_handler != nullptr, "RRC UE handler must not be nullptr"); - return rrc_ue_handler->get_srbs(); - } - -private: - rrc_ue_control_message_handler* rrc_ue_handler = nullptr; -}; - class du_processor_cu_cp_connection_adapter final : public du_connection_notifier { public: diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 5510329549..35f2b5ebd7 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -248,7 +248,7 @@ cu_cp_impl::handle_rrc_reestablishment_request(pci_t old_pci, rnti_t old_c_rnti, return reest_context; } - auto srbs = old_ue->get_rrc_ue_notifier().get_srbs(); + auto srbs = old_ue->get_rrc_ue()->get_srbs(); if (std::find(srbs.begin(), srbs.end(), srb_id_t::srb2) == srbs.end()) { logger.debug("ue={}: SRB2 not setup for this UE - rejecting RRC reestablishment", old_ue_index); reest_context.ue_index = old_ue_index; @@ -283,7 +283,7 @@ async_task cu_cp_impl::handle_rrc_reestablishment_context_modification_req ue->get_security_manager().get_up_as_config(), cu_up_db.find_cu_up_processor(uint_to_cu_up_index(0))->get_e1ap_bearer_context_manager(), du_db.get_du_processor(ue->get_du_index()).get_f1ap_handler(), - ue->get_rrc_ue_notifier(), + ue->get_rrc_ue(), get_cu_cp_rrc_ue_interface(), ue->get_task_sched(), ue->get_up_resource_manager(), @@ -401,8 +401,8 @@ async_task cu_cp_impl::handle_handover_reconfiguration_sent(ue_index_t tar // Notify RRC UE to await ReconfigurationComplete. CORO_AWAIT_VALUE(bool result, ue_mng.find_du_ue(target_ue_index) - ->get_rrc_ue_notifier() - .on_handover_reconfiguration_complete_expected(transaction_id)); + ->get_rrc_ue() + ->handle_handover_reconfiguration_complete_expected(transaction_id)); CORO_RETURN(result); }); @@ -508,7 +508,7 @@ cu_cp_impl::handle_new_pdu_session_resource_setup_request(cu_cp_pdu_session_reso cfg.security.default_security_indication, cu_up_db.find_cu_up_processor(uint_to_cu_up_index(0))->get_e1ap_bearer_context_manager(), du_db.get_du_processor(ue->get_du_index()).get_f1ap_handler(), - ue->get_rrc_ue_notifier(), + ue->get_rrc_ue(), get_cu_cp_rrc_ue_interface(), ue->get_task_sched(), ue->get_up_resource_manager(), @@ -528,7 +528,7 @@ cu_cp_impl::handle_new_pdu_session_resource_modify_request(const cu_cp_pdu_sessi request, cu_up_db.find_cu_up_processor(uint_to_cu_up_index(0))->get_e1ap_bearer_context_manager(), du_db.get_du_processor(ue->get_du_index()).get_f1ap_handler(), - ue->get_rrc_ue_notifier(), + ue->get_rrc_ue(), get_cu_cp_rrc_ue_interface(), ue->get_task_sched(), ue->get_up_resource_manager(), @@ -548,7 +548,7 @@ cu_cp_impl::handle_new_pdu_session_resource_release_command(const cu_cp_pdu_sess command, cu_up_db.find_cu_up_processor(uint_to_cu_up_index(0))->get_e1ap_bearer_context_manager(), du_db.get_du_processor(ue->get_du_index()).get_f1ap_handler(), - ue->get_rrc_ue_notifier(), + ue->get_rrc_ue(), get_cu_cp_rrc_ue_interface(), ue->get_task_sched(), ue->get_up_resource_manager(), @@ -609,8 +609,7 @@ async_task cu_cp_impl::handle_new_handover_command(ue_index_t ue_index, by } // Unpack Handover Command PDU at RRC, to get RRC Reconfig PDU - ho_reconfig_pdu = - ue_mng.find_du_ue(ue_index)->get_rrc_ue_notifier().on_new_rrc_handover_command(std::move(command)); + ho_reconfig_pdu = ue_mng.find_du_ue(ue_index)->get_rrc_ue()->handle_rrc_handover_command(std::move(command)); if (ho_reconfig_pdu.empty()) { logger.warning("ue={}: Could not unpack Handover Command PDU", ue_index); CORO_EARLY_RETURN(false); diff --git a/lib/cu_cp/du_processor/du_processor.h b/lib/cu_cp/du_processor/du_processor.h index 20fe67ba1d..96afcde119 100644 --- a/lib/cu_cp/du_processor/du_processor.h +++ b/lib/cu_cp/du_processor/du_processor.h @@ -74,69 +74,6 @@ class du_processor_cell_info_interface virtual const du_configuration_context* get_context() const = 0; }; -/// Interface to notify an RRC UE about control and srb messages. -class du_processor_rrc_ue_notifier -{ -public: - virtual ~du_processor_rrc_ue_notifier() = default; - - /// \brief Notify the RRC UE to trigger a UE capability transfer procedure. - /// \param[in] msg The new request msg containing the RAT type, etc. - virtual async_task on_ue_capability_transfer_request(const rrc_ue_capability_transfer_request& msg) = 0; - - /// \brief Notify the RRC UE about an RRC Reconfiguration Request. - /// \param[in] msg The new RRC Reconfiguration Request. - /// \returns The result of the rrc reconfiguration. - virtual async_task on_rrc_reconfiguration_request(const rrc_reconfiguration_procedure_request& msg) = 0; - - /// \brief Get the packed UE Capability RAT Container List. - /// \returns The packed UE Capability RAT Container List. - virtual byte_buffer get_packed_ue_capability_rat_container_list() = 0; - - /// \brief Request the RRC Handover Reconfiguration Context. - /// \returns The RRC Handover Reconfiguration Context. - virtual rrc_ue_handover_reconfiguration_context - get_rrc_ue_handover_reconfiguration_context(const rrc_reconfiguration_procedure_request& request) = 0; - - /// \brief Notify the target RRC UE to await a RRC Reconfiguration Complete for a handover. - /// \param[in] transaction_id The transaction ID of the RRC Reconfiguration Complete. - /// \returns True if the RRC Reconfiguration Complete was received, false otherwise. - virtual async_task on_handover_reconfiguration_complete_expected(uint8_t transaction_id) = 0; - - /// \brief Get the RRC UE release context. - /// \returns The release context of the UE. - virtual rrc_ue_release_context get_rrc_ue_release_context(bool requires_rrc_message) = 0; - - /// \brief Get all mobility related information of an UE required for reestablishment, handover, etc. - /// \returns The mobility context of the UE. - virtual rrc_ue_transfer_context get_transfer_context() = 0; - - /// \brief (Re-)generate the RRC measurement config for the current serving cell of the UE. - /// \params[in] current_meas_config The current meas config of the UE (if applicable). - /// \return The measurement config, if present. - virtual std::optional generate_meas_config(std::optional current_meas_config = {}) = 0; - - /// \brief Request the packed Handover Preparation Message. - virtual byte_buffer get_packed_handover_preparation_message() = 0; - - /// \brief Notify about the reception of a new Handover Command PDU. - /// \param[in] cmd The handover command RRC PDU. - /// \returns The RRC Handover Reconfiguration PDU. If the Handover Command PDU is invalid, an empty buffer is - /// returned. - virtual byte_buffer on_new_rrc_handover_command(byte_buffer cmd) = 0; - - /// \brief Request the RRC Handover Command PDU. - /// \returns The RRC Handover Command PDU. - virtual byte_buffer on_rrc_handover_command_required(const rrc_reconfiguration_procedure_request& request, - unsigned transaction_id) = 0; - - /// \brief Create an SRB at the target RRC UE. - virtual void create_srb(const srb_creation_message& msg) = 0; - - /// \brief Get all SRBs of the UE. - virtual static_vector get_srbs() = 0; -}; - /// Interface used by mobility manager to trigger handover routines. class du_processor_mobility_handler { diff --git a/lib/cu_cp/du_processor/du_processor_impl.cpp b/lib/cu_cp/du_processor/du_processor_impl.cpp index 44de44b9cb..38e0262a4b 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.cpp +++ b/lib/cu_cp/du_processor/du_processor_impl.cpp @@ -173,11 +173,6 @@ bool du_processor_impl::create_rrc_ue(cu_cp_ue& ue, return false; } - // Create and connect DU Processor to RRC UE adapter - rrc_ue_adapters[ue.get_ue_index()] = {}; - rrc_ue_adapters.at(ue.get_ue_index()).connect_rrc_ue(rrc_ue->get_rrc_ue_control_message_handler()); - ue.set_rrc_ue_notifier(rrc_ue_adapters.at(ue.get_ue_index())); - // Notify CU-CP about the creation of the RRC UE cu_cp_notifier.on_rrc_ue_created(ue.get_ue_index(), *rrc_ue); diff --git a/lib/cu_cp/du_processor/du_processor_impl.h b/lib/cu_cp/du_processor/du_processor_impl.h index 4b4a6de67f..6c93a23026 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.h +++ b/lib/cu_cp/du_processor/du_processor_impl.h @@ -105,9 +105,6 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public // RRC UE to F1AP adapters std::unordered_map rrc_ue_f1ap_adapters; - // DU processor to RRC UE adapters - std::unordered_map rrc_ue_adapters; - // Components std::unique_ptr f1ap; std::unique_ptr rrc; diff --git a/lib/cu_cp/routines/mobility/handover_reconfiguration_routine.cpp b/lib/cu_cp/routines/mobility/handover_reconfiguration_routine.cpp index 85a16f9013..7ded86d0d8 100644 --- a/lib/cu_cp/routines/mobility/handover_reconfiguration_routine.cpp +++ b/lib/cu_cp/routines/mobility/handover_reconfiguration_routine.cpp @@ -41,7 +41,7 @@ void handover_reconfiguration_routine::operator()(coro_context> logger.debug("source_ue={} target_ue={}: \"{}\" initialized", source_ue.get_ue_index(), target_ue_index, name()); // Get RRC handover reconfiguration context - ho_reconf_ctxt = source_ue.get_rrc_ue_notifier().get_rrc_ue_handover_reconfiguration_context(request); + ho_reconf_ctxt = source_ue.get_rrc_ue()->get_rrc_ue_handover_reconfiguration_context(request); generate_ue_context_modification_request(); diff --git a/lib/cu_cp/routines/mobility/inter_cu_handover_target_routine.cpp b/lib/cu_cp/routines/mobility/inter_cu_handover_target_routine.cpp index a169f6b21a..ee0ed15b2c 100644 --- a/lib/cu_cp/routines/mobility/inter_cu_handover_target_routine.cpp +++ b/lib/cu_cp/routines/mobility/inter_cu_handover_target_routine.cpp @@ -158,7 +158,7 @@ void inter_cu_handover_target_routine::operator()( {} /* No DRB to be removed */, ue_context_setup_response.du_to_cu_rrc_info, {} /* No NAS PDUs required */, - ue->get_rrc_ue_notifier().generate_meas_config(), + ue->get_rrc_ue()->generate_meas_config(), false, false, false, @@ -175,8 +175,7 @@ void inter_cu_handover_target_routine::operator()( unsigned transaction_id = 0; // Get RRC Handover Command container - handover_command_pdu = - ue->get_rrc_ue_notifier().on_rrc_handover_command_required(rrc_reconfig_args, transaction_id); + handover_command_pdu = ue->get_rrc_ue()->get_rrc_handover_command(rrc_reconfig_args, transaction_id); } CORO_RETURN(generate_handover_resource_allocation_response(true)); @@ -273,7 +272,7 @@ void inter_cu_handover_target_routine::create_srb1() srb1_msg.srb_id = srb_id_t::srb1; srb1_msg.pdcp_cfg = {}; srb1_msg.enable_security = true; - ue_mng.find_du_ue(request.ue_index)->get_rrc_ue_notifier().create_srb(srb1_msg); + ue_mng.find_du_ue(request.ue_index)->get_rrc_ue()->create_srb(srb1_msg); } ngap_handover_resource_allocation_response diff --git a/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp b/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp index a29959b89f..350ddb5771 100644 --- a/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp +++ b/lib/cu_cp/routines/mobility/inter_du_handover_routine.cpp @@ -81,7 +81,7 @@ void inter_du_handover_routine::operator()(coro_contextget_rrc_ue_notifier().get_transfer_context(); + source_rrc_context = source_ue->get_rrc_ue()->get_transfer_context(); next_config = to_config_update(source_rrc_context.up_ctx); } @@ -97,7 +97,7 @@ void inter_du_handover_routine::operator()(coro_contextget_rrc_ue_notifier().get_srbs(), source_rrc_context)) { + target_ue_context_setup_request, source_ue->get_rrc_ue()->get_srbs(), source_rrc_context)) { logger.warning("ue={}: \"{}\" failed to generate UeContextSetupRequest", request.source_ue_index, name()); CORO_EARLY_RETURN(response_msg); } @@ -185,7 +185,7 @@ void inter_du_handover_routine::operator()(coro_contextget_rrc_ue_notifier().generate_meas_config(source_rrc_context.meas_cfg), + target_ue->get_rrc_ue()->generate_meas_config(source_rrc_context.meas_cfg), true, /* Reestablish SRBs */ true /* Reestablish DRBs */, true, /* Update keys */ @@ -298,7 +298,7 @@ void inter_du_handover_routine::create_srb(cu_cp_ue* ue, srb_id_t srb_id) srb_msg.srb_id = srb_id; srb_msg.enable_security = true; // TODO: add support for non-default PDCP config. - ue->get_rrc_ue_notifier().create_srb(srb_msg); + ue->get_rrc_ue()->create_srb(srb_msg); } bool inter_du_handover_routine::add_security_context_to_bearer_context_modification( diff --git a/lib/cu_cp/routines/pdu_session_resource_modification_routine.cpp b/lib/cu_cp/routines/pdu_session_resource_modification_routine.cpp index a4b84f86d2..0293450713 100644 --- a/lib/cu_cp/routines/pdu_session_resource_modification_routine.cpp +++ b/lib/cu_cp/routines/pdu_session_resource_modification_routine.cpp @@ -45,7 +45,7 @@ pdu_session_resource_modification_routine::pdu_session_resource_modification_rou const cu_cp_pdu_session_resource_modify_request& modify_request_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& ue_task_sched_, up_resource_manager& up_resource_mng_, @@ -53,7 +53,7 @@ pdu_session_resource_modification_routine::pdu_session_resource_modification_rou modify_request(modify_request_), e1ap_bearer_ctxt_mng(e1ap_bearer_ctxt_mng_), f1ap_ue_ctxt_mng(f1ap_ue_ctxt_mng_), - rrc_ue_notifier(rrc_ue_notifier_), + rrc_ue(rrc_ue_), cu_cp_notifier(cu_cp_notifier_), ue_task_sched(ue_task_sched_), up_resource_mng(up_resource_mng_), @@ -159,7 +159,7 @@ void pdu_session_resource_modification_routine::operator()( {} /* No extra DRB to be removed */, ue_context_modification_response.du_to_cu_rrc_info, nas_pdus, - rrc_ue_notifier.generate_meas_config(), + rrc_ue->generate_meas_config(), false, false, false, @@ -170,7 +170,7 @@ void pdu_session_resource_modification_routine::operator()( } } - CORO_AWAIT_VALUE(rrc_reconfig_result, rrc_ue_notifier.on_rrc_reconfiguration_request(rrc_reconfig_args)); + CORO_AWAIT_VALUE(rrc_reconfig_result, rrc_ue->handle_rrc_reconfiguration_request(rrc_reconfig_args)); // Handle RRC Reconfiguration result. if (handle_procedure_response(response_msg, modify_request, rrc_reconfig_result, logger) == false) { diff --git a/lib/cu_cp/routines/pdu_session_resource_modification_routine.h b/lib/cu_cp/routines/pdu_session_resource_modification_routine.h index de28fb01e5..ddf4a80df7 100644 --- a/lib/cu_cp/routines/pdu_session_resource_modification_routine.h +++ b/lib/cu_cp/routines/pdu_session_resource_modification_routine.h @@ -28,7 +28,7 @@ class pdu_session_resource_modification_routine pdu_session_resource_modification_routine(const cu_cp_pdu_session_resource_modify_request& modify_request_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& ue_task_sched_, up_resource_manager& up_resource_mng_, @@ -49,13 +49,13 @@ class pdu_session_resource_modification_routine up_config_update next_config; - e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP - f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU - du_processor_rrc_ue_notifier& rrc_ue_notifier; // to trigger RRC Reconfiguration at UE - cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP - ue_task_scheduler& ue_task_sched; // to schedule UE release request - up_resource_manager& up_resource_mng; // to get RRC DRB config - srslog::basic_logger& logger; + e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP + f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU + rrc_ue_interface* rrc_ue; // to trigger RRC Reconfiguration at UE + cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP + ue_task_scheduler& ue_task_sched; // to schedule UE release request + up_resource_manager& up_resource_mng; // to get RRC DRB config + srslog::basic_logger& logger; // (sub-)routine requests e1ap_bearer_context_modification_request bearer_context_modification_request; diff --git a/lib/cu_cp/routines/pdu_session_resource_release_routine.cpp b/lib/cu_cp/routines/pdu_session_resource_release_routine.cpp index ff1bdca7d3..4160d5992b 100644 --- a/lib/cu_cp/routines/pdu_session_resource_release_routine.cpp +++ b/lib/cu_cp/routines/pdu_session_resource_release_routine.cpp @@ -19,7 +19,7 @@ pdu_session_resource_release_routine::pdu_session_resource_release_routine( const cu_cp_pdu_session_resource_release_command& release_cmd_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& task_sched_, up_resource_manager& up_resource_mng_, @@ -27,7 +27,7 @@ pdu_session_resource_release_routine::pdu_session_resource_release_routine( release_cmd(release_cmd_), e1ap_bearer_ctxt_mng(e1ap_bearer_ctxt_mng_), f1ap_ue_ctxt_mng(f1ap_ue_ctxt_mng_), - rrc_ue_notifier(rrc_ue_notifier_), + rrc_ue(rrc_ue_), cu_cp_notifier(cu_cp_notifier_), task_sched(task_sched_), up_resource_mng(up_resource_mng_), @@ -131,7 +131,7 @@ void pdu_session_resource_release_routine::operator()( next_config.drb_to_remove_list, ue_context_modification_response.du_to_cu_rrc_info, nas_pdus, - rrc_ue_notifier.generate_meas_config(), + rrc_ue->generate_meas_config(), false, false, false, @@ -142,7 +142,7 @@ void pdu_session_resource_release_routine::operator()( } } - CORO_AWAIT_VALUE(rrc_reconfig_result, rrc_ue_notifier.on_rrc_reconfiguration_request(rrc_reconfig_args)); + CORO_AWAIT_VALUE(rrc_reconfig_result, rrc_ue->handle_rrc_reconfiguration_request(rrc_reconfig_args)); // Handle RRC Reconfiguration result. if (not handle_procedure_response(response_msg, release_cmd, rrc_reconfig_result, logger)) { diff --git a/lib/cu_cp/routines/pdu_session_resource_release_routine.h b/lib/cu_cp/routines/pdu_session_resource_release_routine.h index 88e3cf30bd..b2ff44aca0 100644 --- a/lib/cu_cp/routines/pdu_session_resource_release_routine.h +++ b/lib/cu_cp/routines/pdu_session_resource_release_routine.h @@ -28,7 +28,7 @@ class pdu_session_resource_release_routine pdu_session_resource_release_routine(const cu_cp_pdu_session_resource_release_command& release_cmd_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& task_sched_, up_resource_manager& up_resource_mng_, @@ -48,13 +48,13 @@ class pdu_session_resource_release_routine up_config_update next_config; - e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP - f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU - du_processor_rrc_ue_notifier& rrc_ue_notifier; // to trigger RRC Reconfiguration at UE - cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP - ue_task_scheduler& task_sched; // to schedule UE release request - up_resource_manager& up_resource_mng; // to get RRC DRB config - srslog::basic_logger& logger; + e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP + f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU + rrc_ue_interface* rrc_ue; // to trigger RRC Reconfiguration at UE + cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP + ue_task_scheduler& task_sched; // to schedule UE release request + up_resource_manager& up_resource_mng; // to get RRC DRB config + srslog::basic_logger& logger; // (sub-)routine requests f1ap_ue_context_modification_request ue_context_mod_request; diff --git a/lib/cu_cp/routines/pdu_session_resource_setup_routine.cpp b/lib/cu_cp/routines/pdu_session_resource_setup_routine.cpp index 1b204e1e93..d4dd5e1a4f 100644 --- a/lib/cu_cp/routines/pdu_session_resource_setup_routine.cpp +++ b/lib/cu_cp/routines/pdu_session_resource_setup_routine.cpp @@ -59,7 +59,7 @@ pdu_session_resource_setup_routine::pdu_session_resource_setup_routine( const security_indication_t& default_security_indication_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& ue_task_sched_, up_resource_manager& up_resource_mng_, @@ -70,7 +70,7 @@ pdu_session_resource_setup_routine::pdu_session_resource_setup_routine( default_security_indication(default_security_indication_), e1ap_bearer_ctxt_mng(e1ap_bearer_ctxt_mng_), f1ap_ue_ctxt_mng(f1ap_ue_ctxt_mng_), - rrc_ue_notifier(rrc_ue_notifier_), + rrc_ue(rrc_ue_), cu_cp_notifier(cu_cp_notifier_), ue_task_sched(ue_task_sched_), up_resource_mng(up_resource_mng_), @@ -150,7 +150,7 @@ void pdu_session_resource_setup_routine::operator()( ue_context_mod_request.ue_index = setup_msg.ue_index; ue_context_mod_request.cu_to_du_rrc_info.emplace(); ue_context_mod_request.cu_to_du_rrc_info.value().ue_cap_rat_container_list = - rrc_ue_notifier.get_packed_ue_capability_rat_container_list(); + rrc_ue->get_packed_ue_capability_rat_container_list(); // DRB setup have already added above. CORO_AWAIT_VALUE(ue_context_modification_response, @@ -214,7 +214,7 @@ void pdu_session_resource_setup_routine::operator()( {} /* No extra DRB to be removed */, ue_context_modification_response.du_to_cu_rrc_info, nas_pdus, - next_config.initial_context_creation ? rrc_ue_notifier.generate_meas_config() + next_config.initial_context_creation ? rrc_ue->generate_meas_config() : std::optional{}, false, false, @@ -226,7 +226,7 @@ void pdu_session_resource_setup_routine::operator()( } } - CORO_AWAIT_VALUE(rrc_reconfig_result, rrc_ue_notifier.on_rrc_reconfiguration_request(rrc_reconfig_args)); + CORO_AWAIT_VALUE(rrc_reconfig_result, rrc_ue->handle_rrc_reconfiguration_request(rrc_reconfig_args)); // Handle RRC Reconfiguration Response if (!handle_procedure_response(response_msg, setup_msg, rrc_reconfig_result, logger)) { diff --git a/lib/cu_cp/routines/pdu_session_resource_setup_routine.h b/lib/cu_cp/routines/pdu_session_resource_setup_routine.h index 064f33aa79..c930a734d6 100644 --- a/lib/cu_cp/routines/pdu_session_resource_setup_routine.h +++ b/lib/cu_cp/routines/pdu_session_resource_setup_routine.h @@ -47,7 +47,7 @@ class pdu_session_resource_setup_routine const security_indication_t& default_security_indication_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& ue_task_sched_, up_resource_manager& up_resource_mng_, @@ -70,13 +70,13 @@ class pdu_session_resource_setup_routine up_config_update next_config; - e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP - f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU - du_processor_rrc_ue_notifier& rrc_ue_notifier; // to trigger RRC Reconfiguration at UE - cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP - ue_task_scheduler& ue_task_sched; // to schedule UE release request - up_resource_manager& up_resource_mng; // to get RRC DRB config - srslog::basic_logger& logger; + e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP + f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU + rrc_ue_interface* rrc_ue; // to trigger RRC Reconfiguration at UE + cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP + ue_task_scheduler& ue_task_sched; // to schedule UE release request + up_resource_manager& up_resource_mng; // to get RRC DRB config + srslog::basic_logger& logger; // (sub-)routine requests e1ap_bearer_context_setup_request bearer_context_setup_request; diff --git a/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp b/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp index 2f42a55c73..7042023c45 100644 --- a/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp +++ b/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp @@ -22,7 +22,7 @@ reestablishment_context_modification_routine::reestablishment_context_modificati const srsran::security::sec_as_config& security_cfg_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& ue_task_sched_, up_resource_manager& up_resource_mng_, @@ -31,7 +31,7 @@ reestablishment_context_modification_routine::reestablishment_context_modificati security_cfg(security_cfg_), e1ap_bearer_ctxt_mng(e1ap_bearer_ctxt_mng_), f1ap_ue_ctxt_mng(f1ap_ue_ctxt_mng_), - rrc_ue_notifier(rrc_ue_notifier_), + rrc_ue(rrc_ue_), cu_cp_notifier(cu_cp_notifier_), ue_task_sched(ue_task_sched_), up_resource_mng(up_resource_mng_), @@ -135,7 +135,7 @@ void reestablishment_context_modification_routine::operator()(coro_contexthandle_rrc_reconfiguration_request(rrc_reconfig_args)); // Handle RRC Reconfiguration result. if (not rrc_reconfig_result) { diff --git a/lib/cu_cp/routines/reestablishment_context_modification_routine.h b/lib/cu_cp/routines/reestablishment_context_modification_routine.h index 6b016f9d4f..86eac268d7 100644 --- a/lib/cu_cp/routines/reestablishment_context_modification_routine.h +++ b/lib/cu_cp/routines/reestablishment_context_modification_routine.h @@ -30,7 +30,7 @@ class reestablishment_context_modification_routine const srsran::security::sec_as_config& security_cfg_, e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng_, f1ap_ue_context_manager& f1ap_ue_ctxt_mng_, - du_processor_rrc_ue_notifier& rrc_ue_notifier_, + rrc_ue_interface* rrc_ue_, cu_cp_rrc_ue_interface& cu_cp_notifier_, ue_task_scheduler& ue_task_sched_, up_resource_manager& up_resource_mng_, @@ -53,15 +53,15 @@ class reestablishment_context_modification_routine up_resource_manager& up_resource_manager, bool reestablish_pdcp); - ue_index_t ue_index = ue_index_t::invalid; - security::sec_as_config security_cfg; - e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP - f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU - du_processor_rrc_ue_notifier& rrc_ue_notifier; // to trigger RRC Reconfiguration at UE - cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP - ue_task_scheduler& ue_task_sched; // to schedule UE release request - up_resource_manager& up_resource_mng; // to get RRC DRB config - srslog::basic_logger& logger; + ue_index_t ue_index = ue_index_t::invalid; + security::sec_as_config security_cfg; + e1ap_bearer_context_manager& e1ap_bearer_ctxt_mng; // to trigger bearer context setup at CU-UP + f1ap_ue_context_manager& f1ap_ue_ctxt_mng; // to trigger UE context modification at DU + rrc_ue_interface* rrc_ue; // to trigger RRC Reconfiguration at UE + cu_cp_rrc_ue_interface& cu_cp_notifier; // to trigger UE release at CU-CP + ue_task_scheduler& ue_task_sched; // to schedule UE release request + up_resource_manager& up_resource_mng; // to get RRC DRB config + srslog::basic_logger& logger; // (sub-)routine requests e1ap_bearer_context_modification_request bearer_context_modification_request; diff --git a/lib/cu_cp/routines/ue_context_release_routine.cpp b/lib/cu_cp/routines/ue_context_release_routine.cpp index 300e6087c5..a30541d5e4 100644 --- a/lib/cu_cp/routines/ue_context_release_routine.cpp +++ b/lib/cu_cp/routines/ue_context_release_routine.cpp @@ -45,9 +45,8 @@ void ue_context_release_routine::operator()(coro_contextget_rrc_ue_notifier() - .get_rrc_ue_release_context(command.requires_rrc_release); + release_context = + ue_mng.find_du_ue(command.ue_index)->get_rrc_ue()->get_rrc_ue_release_context(command.requires_rrc_release); release_complete.user_location_info = release_context.user_location_info; } diff --git a/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp b/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp index 2eb0f950ee..d003e534c1 100644 --- a/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp +++ b/lib/cu_cp/ue_manager/cu_cp_ue_impl.cpp @@ -78,13 +78,6 @@ void cu_cp_ue::update_meas_context(cell_meas_manager_ue_context meas_ctxt) meas_context = std::move(meas_ctxt); } -/// \brief Set the RRC UE notifier of the UE. -/// \param[in] rrc_ue_notifier_ RRC UE notifier of the UE. -void cu_cp_ue::set_rrc_ue_notifier(du_processor_rrc_ue_notifier& rrc_ue_notifier_) -{ - rrc_ue_notifier = &rrc_ue_notifier_; -} - /// \brief Set the RRC UE of the UE. /// \param[in] rrc_ue_ RRC UE of the UE. void cu_cp_ue::set_rrc_ue(rrc_ue_interface& rrc_ue_) @@ -97,10 +90,3 @@ ngap_rrc_ue_notifier& cu_cp_ue::get_ngap_rrc_ue_notifier() { return ngap_rrc_ue_ev_notifier; } - -/// \brief Get the RRC UE notifier of the UE. -du_processor_rrc_ue_notifier& cu_cp_ue::get_rrc_ue_notifier() -{ - srsran_assert(rrc_ue_notifier != nullptr, "ue={}: RRC UE notifier was not set", ue_index); - return *rrc_ue_notifier; -} diff --git a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h index bf2504f9d0..7536cd9652 100644 --- a/lib/cu_cp/ue_manager/cu_cp_ue_impl.h +++ b/lib/cu_cp/ue_manager/cu_cp_ue_impl.h @@ -99,10 +99,6 @@ class cu_cp_ue : public cu_cp_ue_impl_interface /// \return True if the DU UE context is created, false otherwise. [[nodiscard]] bool du_ue_created() const { return ue_ctxt.du_idx != du_index_t::invalid; } - /// \brief Set the RRC UE notifier of the UE. - /// \param[in] rrc_ue_notifier_ RRC UE notifier of the UE. - void set_rrc_ue_notifier(du_processor_rrc_ue_notifier& rrc_ue_notifier_); - /// \brief Set the RRC UE of the UE. void set_rrc_ue(rrc_ue_interface& rrc_ue_); @@ -115,9 +111,6 @@ class cu_cp_ue : public cu_cp_ue_impl_interface /// \brief Get the RRC UE CU-CP UE notifier of the UE. rrc_ue_cu_cp_ue_notifier& get_rrc_ue_cu_cp_ue_notifier() { return rrc_ue_cu_cp_ue_ev_notifier; } - /// \brief Get the RRC UE notifier of the UE. - du_processor_rrc_ue_notifier& get_rrc_ue_notifier(); - rrc_ue_context_update_notifier& get_rrc_ue_context_update_notifier() { return rrc_ue_cu_cp_ev_notifier; } /// \brief Get the RRC UE measurement notifier of the UE. @@ -147,8 +140,7 @@ class cu_cp_ue : public cu_cp_ue_impl_interface du_cell_index_t pcell_index = du_cell_index_t::invalid; pci_t pci = INVALID_PCI; - rrc_ue_cu_cp_ue_adapter rrc_ue_cu_cp_ue_ev_notifier; - du_processor_rrc_ue_notifier* rrc_ue_notifier = nullptr; + rrc_ue_cu_cp_ue_adapter rrc_ue_cu_cp_ue_ev_notifier; // rrc ue rrc_ue_interface* rrc_ue = nullptr; diff --git a/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp b/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp index 0a15f15eb2..7959ab60e9 100644 --- a/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp +++ b/tests/unittests/cu_cp/mobility/handover_reconfiguration_routine_test.cpp @@ -18,6 +18,164 @@ using namespace srsran; using namespace srs_cu_cp; +struct dummy_rrc_ue : public rrc_ue_interface, public rrc_ue_controller { +public: + dummy_rrc_ue() = default; + + void set_rrc_reconfiguration_outcome(bool outcome) { rrc_reconfiguration_outcome = outcome; } + + void set_transaction_id(unsigned transaction_id_) { test_transaction_id = transaction_id_; } + + // RRC UE Controller + void stop() override{}; + + // RRC UL PDU handler + void handle_ul_ccch_pdu(byte_buffer pdu) override{}; + void handle_ul_dcch_pdu(const srb_id_t srb_id, byte_buffer pdu) override{}; + + // RRC NGAP Message handler + void handle_dl_nas_transport_message(byte_buffer nas_pdu) override{}; + byte_buffer get_packed_ue_radio_access_cap_info() const override { return byte_buffer{}; }; + byte_buffer get_packed_handover_preparation_message() override { return byte_buffer{}; }; + + // RRC UE Control Message handler + + rrc_ue_security_mode_command_context get_security_mode_command_context() override { return {}; } + + async_task handle_security_mode_complete_expected(uint8_t transaction_id) override + { + logger.info("Awaiting a RRC Security Mode Complete (transaction_id={})", transaction_id); + return launch_async([](coro_context>& ctx) mutable { + CORO_BEGIN(ctx); + CORO_RETURN(true); + }); + } + + byte_buffer get_packed_ue_capability_rat_container_list() const override + { + logger.info("Received a new request to get packed UE capabilities"); + return byte_buffer{}; + } + async_task handle_rrc_reconfiguration_request(const rrc_reconfiguration_procedure_request& msg) override + { + logger.info("Received a new RRC reconfiguration request"); + last_radio_bearer_cfg = msg.radio_bearer_cfg; + + return launch_async([this](coro_context>& ctx) mutable { + CORO_BEGIN(ctx); + CORO_RETURN(rrc_reconfiguration_outcome); + }); + } + + rrc_ue_handover_reconfiguration_context + get_rrc_ue_handover_reconfiguration_context(const rrc_reconfiguration_procedure_request& request) override + { + logger.info("Received a new handover reconfiguration request (transaction_id={})", test_transaction_id); + last_radio_bearer_cfg = request.radio_bearer_cfg; + return {test_transaction_id, byte_buffer{}}; + } + + async_task handle_handover_reconfiguration_complete_expected(uint8_t transaction_id_) override + { + logger.info("Awaiting a RRC Reconfiguration Complete (transaction_id={})", transaction_id_); + last_transaction_id = transaction_id_; + return launch_async([this](coro_context>& ctx) mutable { + CORO_BEGIN(ctx); + CORO_RETURN(rrc_reconfiguration_outcome); + }); + } + + bool store_ue_capabilities(byte_buffer ue_capabilities) override + { + last_ue_capabilities = std::move(ue_capabilities); + return true; + } + + async_task handle_rrc_ue_capability_transfer_request(const rrc_ue_capability_transfer_request& msg) override + { + logger.info("Received a new UE capability transfer request"); + + return launch_async([this](coro_context>& ctx) mutable { + CORO_BEGIN(ctx); + CORO_RETURN(ue_cap_transfer_outcome); + }); + } + + rrc_ue_release_context get_rrc_ue_release_context(bool requires_rrc_msg) override + { + logger.info("Received a new request to get RRC UE release context"); + rrc_ue_release_context release_context; + // TODO: Add values + return release_context; + } + + rrc_ue_transfer_context get_transfer_context() override { return rrc_ue_transfer_context{}; } + + std::optional generate_meas_config(std::optional current_meas_config = {}) override + { + std::optional meas_config; + return meas_config; + } + + byte_buffer handle_rrc_handover_command(byte_buffer cmd) override { return byte_buffer{}; } + + byte_buffer get_rrc_handover_command(const rrc_reconfiguration_procedure_request& request, + unsigned transaction_id_) override + { + logger.info("Received a new request to get a RRC Handover Command."); + return byte_buffer{}; + } + + void create_srb(const srb_creation_message& msg) override + { + logger.info("ue={} Creating {}", msg.ue_index, msg.srb_id); + last_srb_id = msg.srb_id; + srb_vec.push_back(msg.srb_id); + } + + static_vector get_srbs() override { return srb_vec; } + + // RRC UE Setup proc notifier + void on_new_dl_ccch(const asn1::rrc_nr::dl_ccch_msg_s& dl_ccch_msg) override{}; + void on_ue_release_required(const ngap_cause_t& cause) override{}; + + // RRC UE Security Mode Command proc notifier + void on_new_dl_dcch(srb_id_t srb_id, const asn1::rrc_nr::dl_dcch_msg_s& dl_dcch_msg) override{}; + + // RRC UE Reconfiguration proc notifier + + // RRC UE Context handler + rrc_ue_reestablishment_context_response get_context() override + { + logger.info("Received a new request to get RRC UE reestablishment context"); + return rrc_ue_reestablishment_context_response{}; + } + + // RRC UE Reestablishment proc notifier + void on_new_as_security_context() override{}; + + // interface functions + rrc_ue_controller& get_controller() override { return *this; }; + rrc_ul_pdu_handler& get_ul_pdu_handler() override { return *this; }; + rrc_ngap_message_handler& get_rrc_ngap_message_handler() override { return *this; }; + rrc_ue_control_message_handler& get_rrc_ue_control_message_handler() override { return *this; }; + rrc_ue_context_handler& get_rrc_ue_context_handler() override { return *this; }; + + std::optional last_radio_bearer_cfg; + void reset() { last_radio_bearer_cfg.reset(); } + + unsigned last_transaction_id; + srb_id_t last_srb_id; + byte_buffer last_ue_capabilities; + +private: + srslog::basic_logger& logger = srslog::fetch_basic_logger("TEST"); + bool ue_cap_transfer_outcome = true; + bool rrc_reconfiguration_outcome = false; + unsigned test_transaction_id; + static_vector srb_vec; +}; + class handover_reconfiguration_routine_test : public mobility_test { protected: @@ -33,8 +191,8 @@ class handover_reconfiguration_routine_test : public mobility_test du_cell_index_t::min); source_ue = get_ue_manager()->find_ue(source_ue_index); ASSERT_NE(source_ue, nullptr); - source_rrc_ue_notifier.set_transaction_id(transaction_id_); - source_ue->set_rrc_ue_notifier(source_rrc_ue_notifier); + source_rrc_ue.set_transaction_id(transaction_id_); + source_ue->set_rrc_ue(source_rrc_ue); ue_index_t target_ue_index = get_ue_manager()->add_ue(target_du_index, plmn_identity::test_value(), @@ -45,7 +203,7 @@ class handover_reconfiguration_routine_test : public mobility_test target_ue = get_ue_manager()->find_ue(target_ue_index); ASSERT_NE(target_ue, nullptr); cu_cp_handler.set_rrc_reconfiguration_outcome(procedure_outcome); - target_ue->set_rrc_ue_notifier(target_rrc_ue_notifier); + target_ue->set_rrc_ue(target_rrc_ue); } void start_procedure() @@ -70,19 +228,19 @@ class handover_reconfiguration_routine_test : public mobility_test private: // source UE parameters. - du_index_t source_du_index = uint_to_du_index(0); - pci_t source_pci = 1; - rnti_t source_rnti = to_rnti(0x4601); - dummy_du_processor_rrc_ue_notifier source_rrc_ue_notifier; - dummy_f1ap_ue_context_manager source_f1ap_ue_ctxt_mng; - cu_cp_ue* source_ue = nullptr; + du_index_t source_du_index = uint_to_du_index(0); + pci_t source_pci = 1; + rnti_t source_rnti = to_rnti(0x4601); + dummy_rrc_ue source_rrc_ue; + dummy_f1ap_ue_context_manager source_f1ap_ue_ctxt_mng; + cu_cp_ue* source_ue = nullptr; // target UE parameters. - du_index_t target_du_index = uint_to_du_index(1); - pci_t target_pci = 2; - rnti_t target_rnti = to_rnti(0x4601); - dummy_du_processor_rrc_ue_notifier target_rrc_ue_notifier; - cu_cp_ue* target_ue = nullptr; + du_index_t target_du_index = uint_to_du_index(1); + pci_t target_pci = 2; + rnti_t target_rnti = to_rnti(0x4601); + dummy_rrc_ue target_rrc_ue; + cu_cp_ue* target_ue = nullptr; async_task t; std::optional> t_launcher; @@ -90,10 +248,10 @@ class handover_reconfiguration_routine_test : public mobility_test TEST_F(handover_reconfiguration_routine_test, when_reconfiguration_successful_then_return_true) { - unsigned transaction_id = 99; + unsigned test_transaction_id = 99; // Test Preamble. - create_ues(true, transaction_id); + create_ues(true, test_transaction_id); set_sub_procedure_outcome(true); @@ -105,15 +263,15 @@ TEST_F(handover_reconfiguration_routine_test, when_reconfiguration_successful_th // Reconfiguration complete was received. ASSERT_TRUE(get_result()); - ASSERT_TRUE(check_transaction_id(transaction_id)); + ASSERT_TRUE(check_transaction_id(test_transaction_id)); } TEST_F(handover_reconfiguration_routine_test, when_ue_context_mod_unsuccessful_then_return_false) { - unsigned transaction_id = 35; + unsigned test_transaction_id = 35; // Test Preamble. - create_ues(false, transaction_id); + create_ues(false, test_transaction_id); set_sub_procedure_outcome(false); @@ -125,15 +283,15 @@ TEST_F(handover_reconfiguration_routine_test, when_ue_context_mod_unsuccessful_t // Reconfiguration complete was received. ASSERT_FALSE(get_result()); - ASSERT_FALSE(check_transaction_id(transaction_id)); + ASSERT_FALSE(check_transaction_id(test_transaction_id)); } TEST_F(handover_reconfiguration_routine_test, when_reconfiguration_unsuccessful_then_return_false) { - unsigned transaction_id = 17; + unsigned test_transaction_id = 17; // Test Preamble. - create_ues(false, transaction_id); + create_ues(false, test_transaction_id); set_sub_procedure_outcome(true); @@ -145,5 +303,5 @@ TEST_F(handover_reconfiguration_routine_test, when_reconfiguration_unsuccessful_ // Reconfiguration complete was received. ASSERT_FALSE(get_result()); - ASSERT_TRUE(check_transaction_id(transaction_id)); + ASSERT_TRUE(check_transaction_id(test_transaction_id)); } diff --git a/tests/unittests/cu_cp/test_helpers.h b/tests/unittests/cu_cp/test_helpers.h index 02e31e5004..0da7180c83 100644 --- a/tests/unittests/cu_cp/test_helpers.h +++ b/tests/unittests/cu_cp/test_helpers.h @@ -515,109 +515,6 @@ struct dummy_f1ap_ue_context_manager : public f1ap_ue_context_manager { f1ap_ue_context_modification_request ue_context_modifcation_request; }; -struct dummy_du_processor_rrc_ue_notifier : public du_processor_rrc_ue_notifier { -public: - dummy_du_processor_rrc_ue_notifier() = default; - - void set_rrc_reconfiguration_outcome(bool outcome) { rrc_reconfiguration_outcome = outcome; } - - void set_transaction_id(unsigned transaction_id_) { transaction_id = transaction_id_; } - - async_task on_ue_capability_transfer_request(const rrc_ue_capability_transfer_request& msg) override - { - logger.info("Received a new UE capability transfer request"); - - return launch_async([this](coro_context>& ctx) mutable { - CORO_BEGIN(ctx); - CORO_RETURN(ue_cap_transfer_outcome); - }); - } - - async_task on_rrc_reconfiguration_request(const rrc_reconfiguration_procedure_request& msg) override - { - logger.info("Received a new RRC reconfiguration request"); - last_radio_bearer_cfg = msg.radio_bearer_cfg; - - return launch_async([this](coro_context>& ctx) mutable { - CORO_BEGIN(ctx); - CORO_RETURN(rrc_reconfiguration_outcome); - }); - } - - byte_buffer get_packed_ue_capability_rat_container_list() override - { - logger.info("Received a new request to get packed UE capabilities"); - return byte_buffer{}; - } - - rrc_ue_handover_reconfiguration_context - get_rrc_ue_handover_reconfiguration_context(const rrc_reconfiguration_procedure_request& request) override - { - logger.info("Received a new handover reconfiguration request (transaction_id={})", transaction_id); - last_radio_bearer_cfg = request.radio_bearer_cfg; - return {transaction_id, byte_buffer{}}; - } - - async_task on_handover_reconfiguration_complete_expected(uint8_t transaction_id_) override - { - logger.info("Awaiting a RRC Reconfiguration Complete (transaction_id={})", transaction_id_); - last_transaction_id = transaction_id_; - return launch_async([this](coro_context>& ctx) mutable { - CORO_BEGIN(ctx); - CORO_RETURN(rrc_reconfiguration_outcome); - }); - } - - rrc_ue_release_context get_rrc_ue_release_context(bool requires_rrc_msg) override - { - logger.info("Received a new request to get RRC UE release context"); - rrc_ue_release_context release_context; - // TODO: Add values - return release_context; - } - - std::optional generate_meas_config(std::optional current_meas_config = {}) override - { - std::optional meas_config; - return meas_config; - } - - rrc_ue_transfer_context get_transfer_context() override { return rrc_ue_transfer_context{}; } - - byte_buffer get_packed_handover_preparation_message() override { return byte_buffer{}; } - - byte_buffer on_new_rrc_handover_command(byte_buffer cmd) override { return byte_buffer{}; } - - byte_buffer on_rrc_handover_command_required(const rrc_reconfiguration_procedure_request& request, - unsigned transaction_id_) override - { - logger.info("Received a new request to get a RRC Handover Command."); - return byte_buffer{}; - } - - void create_srb(const srb_creation_message& msg) override - { - logger.info("ue={} Creating {}", msg.ue_index, msg.srb_id); - last_srb_id = msg.srb_id; - srb_vec.push_back(msg.srb_id); - } - - static_vector get_srbs() override { return srb_vec; } - - std::optional last_radio_bearer_cfg; - void reset() { last_radio_bearer_cfg.reset(); } - - unsigned last_transaction_id; - srb_id_t last_srb_id; - -private: - srslog::basic_logger& logger = srslog::fetch_basic_logger("TEST"); - bool ue_cap_transfer_outcome = true; - bool rrc_reconfiguration_outcome = false; - unsigned transaction_id; - static_vector srb_vec; -}; - struct dummy_cu_up_processor_cu_up_management_notifier : public cu_up_processor_cu_up_management_notifier { public: dummy_cu_up_processor_cu_up_management_notifier() = default; diff --git a/tests/unittests/cu_cp/ue_manager/ue_manager_test_helpers.h b/tests/unittests/cu_cp/ue_manager/ue_manager_test_helpers.h index 714e525a18..a6dfc55ba5 100644 --- a/tests/unittests/cu_cp/ue_manager/ue_manager_test_helpers.h +++ b/tests/unittests/cu_cp/ue_manager/ue_manager_test_helpers.h @@ -41,8 +41,7 @@ class ue_manager_test : public ::testing::Test ue_manager ue_mng{cu_cp_cfg}; // DU processor to RRC UE adapters - std::unordered_map rrc_ue_adapters; - dummy_ngap_rrc_ue_notifier rrc_ue_pdu_notifier; + dummy_ngap_rrc_ue_notifier rrc_ue_pdu_notifier; }; } // namespace srs_cu_cp From 6d5efdc632798599c98a64eb697563754328f89f Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 16 Sep 2024 18:24:49 +0200 Subject: [PATCH 092/174] cu_cp: remove du processor to f1ap adapter --- lib/cu_cp/adapters/du_processor_adapters.h | 31 -------------------- lib/cu_cp/cu_cp_impl.cpp | 5 ++-- lib/cu_cp/du_processor/du_processor.h | 4 --- lib/cu_cp/du_processor/du_processor_impl.cpp | 1 - lib/cu_cp/du_processor/du_processor_impl.h | 12 ++++---- 5 files changed, 7 insertions(+), 46 deletions(-) diff --git a/lib/cu_cp/adapters/du_processor_adapters.h b/lib/cu_cp/adapters/du_processor_adapters.h index 0df55520b1..f1beaad1dc 100644 --- a/lib/cu_cp/adapters/du_processor_adapters.h +++ b/lib/cu_cp/adapters/du_processor_adapters.h @@ -68,37 +68,6 @@ class du_processor_cu_cp_adapter : public du_processor_cu_cp_notifier cu_cp_ue_context_manipulation_handler* ue_context_handler = nullptr; }; -// Adapter between DU processor and F1AP for UE context -class du_processor_f1ap_ue_context_adapter : public du_processor_f1ap_ue_context_notifier -{ -public: - du_processor_f1ap_ue_context_adapter() = default; - - void connect_f1(f1ap_ue_context_manager& handler_) { handler = &handler_; } - - async_task on_ue_context_release_command(const f1ap_ue_context_release_command& msg) override - { - srsran_assert(handler != nullptr, "F1AP handler must not be nullptr"); - return handler->handle_ue_context_release_command(msg); - } - - async_task - on_ue_context_modification_request(const f1ap_ue_context_modification_request& request) override - { - srsran_assert(handler != nullptr, "F1AP handler must not be nullptr"); - return handler->handle_ue_context_modification_request(request); - } - - bool on_intra_du_reestablishment(ue_index_t ue_index, ue_index_t old_ue_index) override - { - srsran_assert(handler != nullptr, "F1AP handler must not be nullptr"); - return handler->handle_ue_id_update(ue_index, old_ue_index); - } - -private: - f1ap_ue_context_manager* handler = nullptr; -}; - class du_processor_cu_cp_connection_adapter final : public du_connection_notifier { public: diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 35f2b5ebd7..52c059c8db 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -331,9 +331,8 @@ async_task cu_cp_impl::handle_ue_context_transfer(ue_index_t ue_index, ue_ // Notify old F1AP UE context to F1AP. if (old_ue->get_du_index() == ue->get_du_index()) { - const bool result = du_db.get_du_processor(old_ue->get_du_index()) - .get_f1ap_ue_context_notifier() - .on_intra_du_reestablishment(ue_index, old_ue_index); + const bool result = + du_db.get_du_processor(old_ue->get_du_index()).get_f1ap_handler().handle_ue_id_update(ue_index, old_ue_index); if (not result) { logger.warning("The F1AP UE context of the old UE index {} does not exist", old_ue_index); return false; diff --git a/lib/cu_cp/du_processor/du_processor.h b/lib/cu_cp/du_processor/du_processor.h index 96afcde119..64c99fea2d 100644 --- a/lib/cu_cp/du_processor/du_processor.h +++ b/lib/cu_cp/du_processor/du_processor.h @@ -129,10 +129,6 @@ class du_processor : public du_processor_cell_info_interface virtual du_processor_mobility_handler& get_mobility_handler() = 0; - /// \brief Get the F1AP message handler interface of the DU processor object. - /// \return The F1AP message handler interface of the DU processor object. - virtual du_processor_f1ap_ue_context_notifier& get_f1ap_ue_context_notifier() = 0; - /// \brief Retrieve the DU-specific metrics handler. virtual du_metrics_handler& get_metrics_handler() = 0; }; diff --git a/lib/cu_cp/du_processor/du_processor_impl.cpp b/lib/cu_cp/du_processor/du_processor_impl.cpp index 38e0262a4b..0a2abf6c6f 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.cpp +++ b/lib/cu_cp/du_processor/du_processor_impl.cpp @@ -91,7 +91,6 @@ du_processor_impl::du_processor_impl(du_processor_config_t du_proc *f1ap_ev_notifier, *cfg.cu_cp_cfg.services.timers, *cfg.cu_cp_cfg.services.cu_cp_executor); - f1ap_ue_context_notifier.connect_f1(f1ap->get_f1ap_ue_context_manager()); // create RRC rrc_du_creation_message du_creation_req{create_rrc_config(cfg.cu_cp_cfg), rrc_du_cu_cp_notifier}; diff --git a/lib/cu_cp/du_processor/du_processor_impl.h b/lib/cu_cp/du_processor/du_processor_impl.h index 6c93a23026..1466d27646 100644 --- a/lib/cu_cp/du_processor/du_processor_impl.h +++ b/lib/cu_cp/du_processor/du_processor_impl.h @@ -60,9 +60,8 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public metrics_report::du_info handle_du_metrics_report_request() const override; - du_processor_mobility_handler& get_mobility_handler() override { return *this; } - du_processor_f1ap_ue_context_notifier& get_f1ap_ue_context_notifier() override { return f1ap_ue_context_notifier; } - du_metrics_handler& get_metrics_handler() override { return *this; } + du_processor_mobility_handler& get_mobility_handler() override { return *this; } + du_metrics_handler& get_metrics_handler() override { return *this; } private: class f1ap_du_processor_adapter; @@ -91,10 +90,9 @@ class du_processor_impl : public du_processor, public du_metrics_handler, public srslog::basic_logger& logger = srslog::fetch_basic_logger("CU-CP"); du_processor_config_t cfg; - du_processor_cu_cp_notifier& cu_cp_notifier; - f1ap_message_notifier& f1ap_pdu_notifier; - ue_manager& ue_mng; - du_processor_f1ap_ue_context_adapter f1ap_ue_context_notifier; + du_processor_cu_cp_notifier& cu_cp_notifier; + f1ap_message_notifier& f1ap_pdu_notifier; + ue_manager& ue_mng; // F1AP to DU processor adapter std::unique_ptr f1ap_ev_notifier; From 7988a28da5064b7d5d684d0ae78adfa6ac535a18 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 26 Aug 2024 15:51:34 +0200 Subject: [PATCH 093/174] du_high,config: add ra_resp_window config parameter --- apps/units/flexible_du/du_high/du_high_config.h | 3 +++ .../flexible_du/du_high/du_high_config_cli11_schema.cpp | 8 ++++++++ .../flexible_du/du_high/du_high_config_translators.cpp | 1 + .../flexible_du/du_high/du_high_config_yaml_writer.cpp | 3 +++ 4 files changed, 15 insertions(+) diff --git a/apps/units/flexible_du/du_high/du_high_config.h b/apps/units/flexible_du/du_high/du_high_config.h index 10b30bc729..27d462620c 100644 --- a/apps/units/flexible_du/du_high/du_high_config.h +++ b/apps/units/flexible_du/du_high/du_high_config.h @@ -516,6 +516,9 @@ struct du_high_unit_prach_config { /// \c ssb-perRACH-OccasionAndCB-PreamblesPerSSB. /// \remark Values of \c cb_preambles_per_ssb depends on value of \c ssb_per_ro. uint8_t nof_cb_preambles_per_ssb = 64; + /// RA-Response (MSG2) window length in number of slots. Values: {1, 2, 4, 8, 10, 20, 40, 80}. If not specified, it + /// is automatically derived to be equal to 10ms. + std::optional ra_resp_window; }; /// Slice scheduling configuration for a cell. diff --git a/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp b/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp index 3c5a1344d8..d9e5a213ae 100644 --- a/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp @@ -983,6 +983,9 @@ static void configure_cli11_prach_args(CLI::App& app, du_high_unit_prach_config& "Number of Contention Based preambles per SSB") ->default_function([&value = prach_params.nof_cb_preambles_per_ssb]() { return std::to_string(value); }) ->check(CLI::Range(1, 64)); + add_option(app, "--ra_resp_window", prach_params.ra_resp_window, "RA-Response window length in number of slots.") + ->capture_default_str() + ->check(CLI::IsMember({1, 2, 4, 8, 10, 20, 40, 80})); } static void configure_cli11_sib_args(CLI::App& app, du_high_unit_sib_config& sib_params) @@ -1758,6 +1761,11 @@ static void derive_cell_auto_params(du_high_unit_base_cell_config& cell_cfg) cell_cfg.prach_cfg.prach_config_index = 159; } } + + // If PRACH RA Response Window not set, a default one is assigned. + if (not cell_cfg.prach_cfg.ra_resp_window.has_value()) { + cell_cfg.prach_cfg.ra_resp_window = 10U << to_numerology_value(cell_cfg.common_scs); + } } static void derive_auto_params(du_high_unit_config& config) diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index c5b41228f6..c0bfa30ed8 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -362,6 +362,7 @@ std::vector srsran::generate_du_cell_config(const du_hig // PRACH config. rach_config_common& rach_cfg = *out_cell.ul_cfg_common.init_ul_bwp.rach_cfg_common; rach_cfg.rach_cfg_generic.prach_config_index = base_cell.prach_cfg.prach_config_index.value(); + rach_cfg.rach_cfg_generic.ra_resp_window = base_cell.prach_cfg.ra_resp_window.value(); rach_cfg.rach_cfg_generic.preamble_trans_max = base_cell.prach_cfg.preamble_trans_max; rach_cfg.rach_cfg_generic.power_ramping_step_db = base_cell.prach_cfg.power_ramping_step_db; rach_cfg.msg3_transform_precoder = cell.cell.pusch_cfg.enable_transform_precoding; diff --git a/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp b/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp index 5d359abca0..20a5f3ff00 100644 --- a/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp @@ -458,6 +458,9 @@ static YAML::Node build_du_high_prach_section(const du_high_unit_prach_config& c node["ports"].push_back(static_cast(id)); } node["ports"].SetStyle(YAML::EmitterStyle::Flow); + if (config.ra_resp_window.has_value()) { + node["ra_resp_window"] = config.ra_resp_window.value(); + } return node; } From fbe1817dedfea405db8c05e8d4e1cf747bcbb748 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 6 Sep 2024 14:29:15 +0200 Subject: [PATCH 094/174] du,band_helper: check if unlicensend band, validate RAR response window --- .../du_high/du_high_config_validator.cpp | 13 +++++++++++++ include/srsran/ran/band_helper.h | 6 ++++++ lib/ran/band_helper.cpp | 15 +++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/apps/units/flexible_du/du_high/du_high_config_validator.cpp b/apps/units/flexible_du/du_high/du_high_config_validator.cpp index 7b2ba7a2fa..66222aee59 100644 --- a/apps/units/flexible_du/du_high/du_high_config_validator.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_validator.cpp @@ -830,6 +830,19 @@ static bool validate_cells_unit_config(span conf fmt::print("Invalid Sector ID {}, for a gNB Id of {} bits\n", cell.cell.sector_id.value(), gnb_id.bit_length); return false; } + const auto band = cell.cell.band.value_or(band_helper::get_band_from_dl_arfcn(cell.cell.dl_f_ref_arfcn)); + bool is_unlicensed = band_helper::is_unlicensed_band(band); + unsigned int max_ra_resp_window = is_unlicensed ? 40 : 10; + unsigned int ra_resp_window_ms = + cell.cell.prach_cfg.ra_resp_window.value() >> to_numerology_value(cell.cell.common_scs); + if (ra_resp_window_ms > max_ra_resp_window) { + fmt::print("RA Response Window ({}sl -> {}ms) must be smaller than {}ms in {} bands.\n", + cell.cell.prach_cfg.ra_resp_window, + ra_resp_window_ms, + max_ra_resp_window, + is_unlicensed ? "unlicensed" : "licensed"); + return false; + } } // Checks parameter collisions between cells that can lead to problems. diff --git a/include/srsran/ran/band_helper.h b/include/srsran/ran/band_helper.h index 6a84338b72..bbf71edca5 100644 --- a/include/srsran/ran/band_helper.h +++ b/include/srsran/ran/band_helper.h @@ -142,6 +142,12 @@ subcarrier_spacing get_most_suitable_ssb_scs(nr_band band, subcarrier_spacing sc /// \return true for paired spectrum, false otherwise. bool is_paired_spectrum(nr_band band); +/// \brief Returns boolean indicating whether the band is an unlicensed band. +/// \remark Unlicensed bands are CBRS and U-NII-x. +/// \param[in] band Given band. +/// \return true for unlicensed band, false otherwise. +bool is_unlicensed_band(nr_band band); + /// \brief Returns boolean indicating whether the band belongs to FR1 or FR2. /// \param[in] band Given band. /// \remark The input band must be a valid NR band; the function does not return an error in case of invalid band. diff --git a/lib/ran/band_helper.cpp b/lib/ran/band_helper.cpp index 5e468832a1..0c888aa2e3 100644 --- a/lib/ran/band_helper.cpp +++ b/lib/ran/band_helper.cpp @@ -951,6 +951,21 @@ bool srsran::band_helper::is_paired_spectrum(nr_band band) return mode == duplex_mode::FDD; } +bool srsran::band_helper::is_unlicensed_band(nr_band band) +{ + srsran_assert(band != nr_band::invalid, "Band must be a valid NR band."); + switch (band) { + case nr_band::n46: + case nr_band::n48: + case nr_band::n96: + case nr_band::n102: + case nr_band::n104: + return true; + default: + return false; + } +} + frequency_range srsran::band_helper::get_freq_range(nr_band band) { srsran_assert(band != nr_band::invalid, "Band must be a valid NR band."); From ca15b09f0584fc235274f365d89209caeef85508 Mon Sep 17 00:00:00 2001 From: sauka Date: Tue, 17 Sep 2024 11:30:52 +0300 Subject: [PATCH 095/174] ofh: make vlan tag optional --- .../flexible_du/split_7_2/ru_ofh_config.h | 4 +- .../split_7_2/ru_ofh_config_yaml_writer.cpp | 8 +++- .../srsran/ofh/ethernet/ethernet_factories.h | 9 ++-- ...ame_builder.h => ethernet_frame_builder.h} | 17 ++++--- .../ofh/ethernet/vlan_ethernet_frame_params.h | 3 +- include/srsran/ofh/ofh_sector_config.h | 4 +- .../ofh/receiver/ofh_receiver_configuration.h | 2 +- .../ofh_transmitter_configuration.h | 6 +-- include/srsran/ru/ru_ofh_configuration.h | 4 +- lib/ofh/ethernet/CMakeLists.txt | 1 + lib/ofh/ethernet/ethernet_factories.cpp | 10 ++++- .../ethernet/ethernet_frame_builder_impl.cpp | 37 ++++++++++++++++ .../ethernet/ethernet_frame_builder_impl.h | 39 ++++++++++++++++ .../vlan_ethernet_frame_builder_impl.cpp | 9 +++- .../vlan_ethernet_frame_builder_impl.h | 15 +++++-- ...a_flow_cplane_scheduling_commands_impl.cpp | 5 +-- ...ata_flow_cplane_scheduling_commands_impl.h | 9 ++-- ...fh_data_flow_uplane_downlink_data_impl.cpp | 3 +- .../ofh_data_flow_uplane_downlink_data_impl.h | 29 ++++++------ .../transmitter/ofh_transmitter_factories.cpp | 44 +++++++++++-------- .../vlan_ethernet_frame_builder_test.cpp | 26 ++++++++++- ...vlan_ethernet_frame_builder_test_doubles.h | 12 +++-- ...a_flow_cplane_scheduling_commands_test.cpp | 3 +- ...ta_flow_uplane_downlink_data_impl_test.cpp | 15 ++++--- 24 files changed, 220 insertions(+), 94 deletions(-) rename include/srsran/ofh/ethernet/{vlan_ethernet_frame_builder.h => ethernet_frame_builder.h} (54%) create mode 100644 lib/ofh/ethernet/ethernet_frame_builder_impl.cpp create mode 100644 lib/ofh/ethernet/ethernet_frame_builder_impl.h diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config.h b/apps/units/flexible_du/split_7_2/ru_ofh_config.h index 7311164a67..f5cab35d6a 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_config.h +++ b/apps/units/flexible_du/split_7_2/ru_ofh_config.h @@ -89,9 +89,9 @@ struct ru_ofh_unit_cell_config { /// Distributed Unit MAC address. std::string du_mac_address = "00:11:22:33:00:77"; /// V-LAN Tag control information field for C-Plane. - uint16_t vlan_tag_cp = 1U; + std::optional vlan_tag_cp; /// V-LAN Tag control information field for U-Plane. - uint16_t vlan_tag_up = 1U; + std::optional vlan_tag_up; /// RU PRACH port. std::vector ru_prach_port_id = {4, 5}; /// RU Downlink port. diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.cpp b/apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.cpp index d4032f25ae..78a600453d 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.cpp +++ b/apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.cpp @@ -108,8 +108,12 @@ static YAML::Node build_ru_ofh_cell_section(const ru_ofh_unit_cell_config& confi node["mtu"] = config.mtu_size.value(); node["ru_mac_addr"] = config.ru_mac_address; node["du_mac_addr"] = config.du_mac_address; - node["vlan_tag_cp"] = config.vlan_tag_cp; - node["vlan_tag_up"] = config.vlan_tag_up; + if (config.vlan_tag_cp.has_value()) { + node["vlan_tag_cp"] = config.vlan_tag_cp.value(); + } + if (config.vlan_tag_up.has_value()) { + node["vlan_tag_up"] = config.vlan_tag_up.value(); + } for (auto id : config.ru_prach_port_id) { node["prach_port_id"] = id; } diff --git a/include/srsran/ofh/ethernet/ethernet_factories.h b/include/srsran/ofh/ethernet/ethernet_factories.h index a17e77b599..2a3a8a961a 100644 --- a/include/srsran/ofh/ethernet/ethernet_factories.h +++ b/include/srsran/ofh/ethernet/ethernet_factories.h @@ -10,10 +10,10 @@ #pragma once +#include "srsran/ofh/ethernet/ethernet_frame_builder.h" #include "srsran/ofh/ethernet/ethernet_gateway.h" #include "srsran/ofh/ethernet/ethernet_gw_config.h" #include "srsran/ofh/ethernet/ethernet_receiver.h" -#include "srsran/ofh/ethernet/vlan_ethernet_frame_builder.h" #include "srsran/ofh/ethernet/vlan_ethernet_frame_decoder.h" #include "srsran/srslog/logger.h" #include @@ -35,8 +35,11 @@ std::unique_ptr create_receiver(const std::string& interface, task_executor& executor, srslog::basic_logger& logger); -/// Creates an Ethernet VLAN frame builder. -std::unique_ptr create_vlan_frame_builder(); +/// Creates an Ethernet frame builder with VLAN tag insertion. +std::unique_ptr create_vlan_frame_builder(const vlan_frame_params& eth_params); + +/// Creates an Ethernet frame builder without VLAN tag insertion. +std::unique_ptr create_frame_builder(const vlan_frame_params& eth_params); /// Creates an Ethernet VLAN frame decoder. std::unique_ptr create_vlan_frame_decoder(srslog::basic_logger& logger); diff --git a/include/srsran/ofh/ethernet/vlan_ethernet_frame_builder.h b/include/srsran/ofh/ethernet/ethernet_frame_builder.h similarity index 54% rename from include/srsran/ofh/ethernet/vlan_ethernet_frame_builder.h rename to include/srsran/ofh/ethernet/ethernet_frame_builder.h index e91134ba74..ad87452c6d 100644 --- a/include/srsran/ofh/ethernet/vlan_ethernet_frame_builder.h +++ b/include/srsran/ofh/ethernet/ethernet_frame_builder.h @@ -17,26 +17,25 @@ namespace srsran { namespace ether { -/// \brief Describes the VLAN Ethernet frame builder. +/// \brief Describes the Ethernet frame builder. /// -/// Builds a VLAN Ethernet frame following the IEEE 802.3 and IEEE 802.1Q specifications. -class vlan_frame_builder +/// Builds an Ethernet frame following the IEEE 802.3 and IEEE 802.1Q specifications. +class frame_builder { public: /// Default destructor. - virtual ~vlan_frame_builder() = default; + virtual ~frame_builder() = default; - /// Returns the VLAN Ethernet header size in bytes. + /// Returns the Ethernet header size in bytes. virtual units::bytes get_header_size() const = 0; - /// \brief Builds a VLAN Ethernet frame using the given parameters into \c buffer. + /// \brief Builds an Ethernet frame using the given parameters into \c buffer. /// /// This function expects that the buffer already contains the payload of the frame. The builder will write the - /// header in the first \ref vlan_ethernet_frame_builder::get_header_size bytes of the buffer. + /// header in the first \ref frame_builder::get_header_size bytes of the buffer. /// /// \param[in] buffer Buffer where the frame will be built. - /// \param[in] eth_params Ethernet message parameters. - virtual void build_vlan_frame(span buffer, const vlan_frame_params& eth_params) = 0; + virtual void build_frame(span buffer) = 0; }; } // namespace ether diff --git a/include/srsran/ofh/ethernet/vlan_ethernet_frame_params.h b/include/srsran/ofh/ethernet/vlan_ethernet_frame_params.h index 46318aaab2..4ef5c8772c 100644 --- a/include/srsran/ofh/ethernet/vlan_ethernet_frame_params.h +++ b/include/srsran/ofh/ethernet/vlan_ethernet_frame_params.h @@ -11,6 +11,7 @@ #pragma once #include "srsran/ofh/ethernet/ethernet_mac_address.h" +#include namespace srsran { namespace ether { @@ -22,7 +23,7 @@ struct vlan_frame_params { /// Source MAC address. mac_address mac_src_address; /// Tag control information field. - uint16_t tci; + std::optional tci; /// Ethernet type field. uint16_t eth_type; }; diff --git a/include/srsran/ofh/ofh_sector_config.h b/include/srsran/ofh/ofh_sector_config.h index bcaad0a321..be20e0b650 100644 --- a/include/srsran/ofh/ofh_sector_config.h +++ b/include/srsran/ofh/ofh_sector_config.h @@ -44,9 +44,9 @@ struct sector_configuration { /// Source MAC address, corresponds to the Distributed Unit MAC address. ether::mac_address mac_src_address; /// Tag control information field for C-Plane. - uint16_t tci_cp; + std::optional tci_cp; /// Tag control information field for U-Plane. - uint16_t tci_up; + std::optional tci_up; /// DU transmission window timing parameters. tx_window_timing_parameters tx_window_timing_params; diff --git a/include/srsran/ofh/receiver/ofh_receiver_configuration.h b/include/srsran/ofh/receiver/ofh_receiver_configuration.h index f5237d5c7a..a24e7057a6 100644 --- a/include/srsran/ofh/receiver/ofh_receiver_configuration.h +++ b/include/srsran/ofh/receiver/ofh_receiver_configuration.h @@ -37,7 +37,7 @@ struct receiver_config { /// Source MAC address. ether::mac_address mac_src_address; /// Tag control information field. - uint16_t tci; + std::optional tci; /// Reception window timing parameters. rx_window_timing_parameters rx_timing_params; /// \brief RU operating bandwidth. diff --git a/include/srsran/ofh/transmitter/ofh_transmitter_configuration.h b/include/srsran/ofh/transmitter/ofh_transmitter_configuration.h index 43099159b2..50b3b5ad10 100644 --- a/include/srsran/ofh/transmitter/ofh_transmitter_configuration.h +++ b/include/srsran/ofh/transmitter/ofh_transmitter_configuration.h @@ -14,8 +14,8 @@ #include "srsran/adt/static_vector.h" #include "srsran/ofh/compression/iq_compressor.h" #include "srsran/ofh/ecpri/ecpri_packet_builder.h" +#include "srsran/ofh/ethernet/ethernet_frame_builder.h" #include "srsran/ofh/ethernet/ethernet_gateway.h" -#include "srsran/ofh/ethernet/vlan_ethernet_frame_builder.h" #include "srsran/ofh/ofh_constants.h" #include "srsran/ofh/serdes/ofh_cplane_message_builder.h" #include "srsran/ofh/serdes/ofh_uplane_message_builder.h" @@ -52,9 +52,9 @@ struct transmitter_config { /// Source MAC address. ether::mac_address mac_src_address; /// Tag control information field for C-Plane. - uint16_t tci_cp; + std::optional tci_cp; /// Tag control information field for U-Plane. - uint16_t tci_up; + std::optional tci_up; /// Ethernet interface name or identifier. std::string interface; /// Promiscuous mode flag. diff --git a/include/srsran/ru/ru_ofh_configuration.h b/include/srsran/ru/ru_ofh_configuration.h index b7d411482f..90fc38e4e7 100644 --- a/include/srsran/ru/ru_ofh_configuration.h +++ b/include/srsran/ru/ru_ofh_configuration.h @@ -75,9 +75,9 @@ struct ru_ofh_sector_configuration { /// Source MAC address, corresponds to Distributed Unit MAC address. ether::mac_address mac_src_address; /// Tag control information field for C-Plane. - uint16_t tci_cp; + std::optional tci_cp; /// Tag control information field for U-Plane. - uint16_t tci_up; + std::optional tci_up; /// PRACH eAxC. static_vector prach_eaxc; diff --git a/lib/ofh/ethernet/CMakeLists.txt b/lib/ofh/ethernet/CMakeLists.txt index 31b770e493..37143d9b4c 100644 --- a/lib/ofh/ethernet/CMakeLists.txt +++ b/lib/ofh/ethernet/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES ethernet_factories.cpp + ethernet_frame_builder_impl.cpp ethernet_transmitter_impl.cpp ethernet_receiver_impl.cpp ethernet_rx_buffer_impl.cpp diff --git a/lib/ofh/ethernet/ethernet_factories.cpp b/lib/ofh/ethernet/ethernet_factories.cpp index 59fdddb5d6..4f57e31781 100644 --- a/lib/ofh/ethernet/ethernet_factories.cpp +++ b/lib/ofh/ethernet/ethernet_factories.cpp @@ -9,6 +9,7 @@ */ #include "srsran/ofh/ethernet/ethernet_factories.h" +#include "ethernet_frame_builder_impl.h" #include "ethernet_receiver_impl.h" #include "ethernet_transmitter_impl.h" #include "vlan_ethernet_frame_builder_impl.h" @@ -30,9 +31,14 @@ std::unique_ptr srsran::ether::create_receiver(const std::string& i return std::make_unique(interface, is_promiscuous_mode_enabled, executor, logger); } -std::unique_ptr srsran::ether::create_vlan_frame_builder() +std::unique_ptr srsran::ether::create_vlan_frame_builder(const vlan_frame_params& eth_params) { - return std::make_unique(); + return std::make_unique(eth_params); +} + +std::unique_ptr srsran::ether::create_frame_builder(const vlan_frame_params& eth_params) +{ + return std::make_unique(eth_params); } std::unique_ptr srsran::ether::create_vlan_frame_decoder(srslog::basic_logger& logger) diff --git a/lib/ofh/ethernet/ethernet_frame_builder_impl.cpp b/lib/ofh/ethernet/ethernet_frame_builder_impl.cpp new file mode 100644 index 0000000000..d054683894 --- /dev/null +++ b/lib/ofh/ethernet/ethernet_frame_builder_impl.cpp @@ -0,0 +1,37 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "ethernet_frame_builder_impl.h" +#include "../support/network_order_binary_serializer.h" +#include "ethernet_constants.h" + +using namespace srsran; +using namespace ether; + +frame_builder_impl::frame_builder_impl(const srsran::ether::vlan_frame_params& eth_params_) : eth_params(eth_params_) {} + +units::bytes frame_builder_impl::get_header_size() const +{ + return ETH_HEADER_SIZE; +} + +void frame_builder_impl::build_frame(span buffer) +{ + ofh::network_order_binary_serializer serializer(buffer.data()); + + // Write destination MAC address (6 Bytes). + serializer.write(eth_params.mac_dst_address); + + // Write source MAC address (6 Bytes). + serializer.write(eth_params.mac_src_address); + + // Write Ethernet Type (2 Bytes). + serializer.write(eth_params.eth_type); +} diff --git a/lib/ofh/ethernet/ethernet_frame_builder_impl.h b/lib/ofh/ethernet/ethernet_frame_builder_impl.h new file mode 100644 index 0000000000..4dd1f49f22 --- /dev/null +++ b/lib/ofh/ethernet/ethernet_frame_builder_impl.h @@ -0,0 +1,39 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/ofh/ethernet/ethernet_frame_builder.h" + +namespace srsran { +namespace ether { + +/// Implementation for the Ethernet frame builder with no VLAN tag insertion. +class frame_builder_impl : public frame_builder +{ +public: + /// Constructor. + /// + /// \param[in] eth_params Ethernet message parameters. + explicit frame_builder_impl(const vlan_frame_params& eth_params); + + // See interface for documentation. + units::bytes get_header_size() const override; + + // See interface for documentation. + void build_frame(span buffer) override; + +private: + /// Ethernet message parameters. + const vlan_frame_params eth_params; +}; + +} // namespace ether +} // namespace srsran diff --git a/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.cpp b/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.cpp index f516852cb0..607f11fdbb 100644 --- a/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.cpp +++ b/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.cpp @@ -15,12 +15,17 @@ using namespace srsran; using namespace ether; +vlan_frame_builder_impl::vlan_frame_builder_impl(const srsran::ether::vlan_frame_params& eth_params_) : + eth_params(eth_params_) +{ +} + units::bytes vlan_frame_builder_impl::get_header_size() const { return ETH_HEADER_SIZE + ETH_VLAN_TAG_SIZE; } -void vlan_frame_builder_impl::build_vlan_frame(span buffer, const vlan_frame_params& eth_params) +void vlan_frame_builder_impl::build_frame(span buffer) { ofh::network_order_binary_serializer serializer(buffer.data()); @@ -34,7 +39,7 @@ void vlan_frame_builder_impl::build_vlan_frame(span buffer, const vlan_ serializer.write(VLAN_TPID); // Write VLAN TCI (2 Bytes). - serializer.write(eth_params.tci); + serializer.write(eth_params.tci.value()); // Write Ethernet Type (2 Bytes). serializer.write(eth_params.eth_type); diff --git a/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.h b/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.h index d917545859..4f423b2db8 100644 --- a/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.h +++ b/lib/ofh/ethernet/vlan_ethernet_frame_builder_impl.h @@ -10,20 +10,29 @@ #pragma once -#include "srsran/ofh/ethernet/vlan_ethernet_frame_builder.h" +#include "srsran/ofh/ethernet/ethernet_frame_builder.h" namespace srsran { namespace ether { /// Implementation for the VLAN Ethernet frame builder. -class vlan_frame_builder_impl : public vlan_frame_builder +class vlan_frame_builder_impl : public frame_builder { public: + /// Constructor. + /// + /// \param[in] eth_params Ethernet message parameters. + explicit vlan_frame_builder_impl(const vlan_frame_params& eth_params); + // See interface for documentation. units::bytes get_header_size() const override; // See interface for documentation. - void build_vlan_frame(span buffer, const vlan_frame_params& eth_params) override; + void build_frame(span buffer) override; + +private: + /// Ethernet message parameters. + const vlan_frame_params eth_params; }; } // namespace ether diff --git a/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.cpp b/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.cpp index 8c4b16bb87..6a1e56d788 100644 --- a/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.cpp +++ b/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.cpp @@ -136,7 +136,6 @@ data_flow_cplane_scheduling_commands_impl::data_flow_cplane_scheduling_commands_ dl_compr_params(config.dl_compr_params), ul_compr_params(config.ul_compr_params), prach_compr_params(config.prach_compr_params), - vlan_params(config.vlan_params), ul_cplane_context_repo(std::move(dependencies.ul_cplane_context_repo)), frame_pool(std::move(dependencies.frame_pool)), eth_builder(std::move(dependencies.eth_builder)), @@ -206,7 +205,7 @@ void data_flow_cplane_scheduling_commands_impl::enqueue_section_type_1_message( // Add Ethernet header. span eth_buffer = span(buffer).first(ether_hdr_size.value() + bytes_written); - eth_builder->build_vlan_frame(eth_buffer, vlan_params); + eth_builder->build_frame(eth_buffer); frame_buffer.set_size(eth_buffer.size()); } @@ -269,7 +268,7 @@ void data_flow_cplane_scheduling_commands_impl::enqueue_section_type_3_prach_mes // Add Ethernet header. span eth_buffer = span(buffer).first(ether_hdr_size.value() + bytes_written); - eth_builder->build_vlan_frame(eth_buffer, vlan_params); + eth_builder->build_frame(eth_buffer); frame_buffer.set_size(eth_buffer.size()); } diff --git a/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.h b/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.h index 510588d9b2..c673d9ff91 100644 --- a/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.h +++ b/lib/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_impl.h @@ -14,8 +14,8 @@ #include "ofh_data_flow_cplane_scheduling_commands.h" #include "sequence_identifier_generator.h" #include "srsran/ofh/ecpri/ecpri_packet_builder.h" +#include "srsran/ofh/ethernet/ethernet_frame_builder.h" #include "srsran/ofh/ethernet/ethernet_frame_pool.h" -#include "srsran/ofh/ethernet/vlan_ethernet_frame_builder.h" #include "srsran/ofh/serdes/ofh_cplane_message_builder.h" namespace srsran { @@ -27,8 +27,6 @@ struct data_flow_cplane_scheduling_commands_impl_config { unsigned ru_nof_prbs; /// Cyclic prefix. cyclic_prefix cp; - /// VLAN frame parameters. - ether::vlan_frame_params vlan_params; /// Downlink compression parameters. ru_compression_params dl_compr_params; /// Uplink compression parameters. @@ -46,7 +44,7 @@ struct data_flow_cplane_scheduling_commands_impl_dependencies { /// Ethernet frame pool. std::shared_ptr frame_pool; /// VLAN frame builder. - std::unique_ptr eth_builder; + std::unique_ptr eth_builder; /// eCPRI packet builder. std::unique_ptr ecpri_builder; /// Control-Plane message builder. @@ -74,12 +72,11 @@ class data_flow_cplane_scheduling_commands_impl : public data_flow_cplane_schedu const ru_compression_params dl_compr_params; const ru_compression_params ul_compr_params; const ru_compression_params prach_compr_params; - const ether::vlan_frame_params vlan_params; sequence_identifier_generator cp_dl_seq_gen; sequence_identifier_generator cp_ul_seq_gen; std::shared_ptr ul_cplane_context_repo; std::shared_ptr frame_pool; - std::unique_ptr eth_builder; + std::unique_ptr eth_builder; std::unique_ptr ecpri_builder; std::unique_ptr cp_builder; }; diff --git a/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.cpp b/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.cpp index 34d7ec6e48..5de2d87908 100644 --- a/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.cpp +++ b/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.cpp @@ -65,7 +65,6 @@ data_flow_uplane_downlink_data_impl::data_flow_uplane_downlink_data_impl( logger(*dependencies.logger), nof_symbols_per_slot(get_nsymb_per_slot(config.cp)), ru_nof_prbs(config.ru_nof_prbs), - vlan_params(config.vlan_params), compr_params(config.compr_params), frame_pool(std::move(dependencies.frame_pool)), compressor_sel(std::move(dependencies.compressor_sel)), @@ -192,7 +191,7 @@ unsigned data_flow_uplane_downlink_data_impl::enqueue_section_type_1_message_sym // Add Ethernet header. span eth_buffer = span(buffer).first(ether_header_size.value() + bytes_written); - eth_builder->build_vlan_frame(eth_buffer, vlan_params); + eth_builder->build_frame(eth_buffer); logger.debug("Packing a downlink User-Plane message for slot '{}' and eAxC '{}', symbol_id '{}', PRB range '{}:{}', " "size '{}' bytes", diff --git a/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.h b/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.h index d499a18bf9..370aecc14a 100644 --- a/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.h +++ b/lib/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl.h @@ -15,7 +15,7 @@ #include "srsran/instrumentation/traces/ofh_traces.h" #include "srsran/ofh/compression/iq_compressor.h" #include "srsran/ofh/ecpri/ecpri_packet_builder.h" -#include "srsran/ofh/ethernet/vlan_ethernet_frame_builder.h" +#include "srsran/ofh/ethernet/ethernet_frame_builder.h" #include "srsran/ofh/serdes/ofh_uplane_message_builder.h" #include "srsran/ran/cyclic_prefix.h" #include "srsran/srslog/srslog.h" @@ -37,8 +37,6 @@ struct data_flow_uplane_downlink_data_impl_config { unsigned ru_nof_prbs; /// Downlink eAxCs. static_vector dl_eaxc; - /// VLAN frame parameters. - ether::vlan_frame_params vlan_params; /// Compression parameters. ru_compression_params compr_params; }; @@ -50,7 +48,7 @@ struct data_flow_uplane_downlink_data_impl_dependencies { /// Ethernet frame pool. std::shared_ptr frame_pool; /// VLAN frame builder. - std::unique_ptr eth_builder; + std::unique_ptr eth_builder; /// eCPRI packet builder. std::unique_ptr ecpri_builder; /// IQ compressor. @@ -109,18 +107,17 @@ class data_flow_uplane_downlink_data_impl : public data_flow_uplane_downlink_dat span buffer); private: - srslog::basic_logger& logger; - const unsigned nof_symbols_per_slot; - const unsigned ru_nof_prbs; - const ether::vlan_frame_params vlan_params; - const ru_compression_params compr_params; - sequence_identifier_generator up_seq_gen; - std::shared_ptr frame_pool; - std::unique_ptr compressor_sel; - std::unique_ptr eth_builder; - std::unique_ptr ecpri_builder; - std::unique_ptr up_builder; - ofh_uplane_trace_names formatted_trace_names; + srslog::basic_logger& logger; + const unsigned nof_symbols_per_slot; + const unsigned ru_nof_prbs; + const ru_compression_params compr_params; + sequence_identifier_generator up_seq_gen; + std::shared_ptr frame_pool; + std::unique_ptr compressor_sel; + std::unique_ptr eth_builder; + std::unique_ptr ecpri_builder; + std::unique_ptr up_builder; + ofh_uplane_trace_names formatted_trace_names; }; } // namespace ofh diff --git a/lib/ofh/transmitter/ofh_transmitter_factories.cpp b/lib/ofh/transmitter/ofh_transmitter_factories.cpp index 17c04d28e7..d996ea69f3 100644 --- a/lib/ofh/transmitter/ofh_transmitter_factories.cpp +++ b/lib/ofh/transmitter/ofh_transmitter_factories.cpp @@ -35,20 +35,23 @@ create_data_flow_cplane_sched(const transmitter_config& config.ru_nof_prbs = get_max_Nprb(bs_channel_bandwidth_to_MHz(tx_config.ru_working_bw), tx_config.scs, srsran::frequency_range::FR1); - config.vlan_params.eth_type = ether::ECPRI_ETH_TYPE; - config.vlan_params.tci = tx_config.tci_cp; - config.vlan_params.mac_dst_address = tx_config.mac_dst_address; - config.vlan_params.mac_src_address = tx_config.mac_src_address; - config.dl_compr_params = tx_config.dl_compr_params; - config.ul_compr_params = tx_config.ul_compr_params; - config.prach_compr_params = tx_config.prach_compr_params; - config.cp = tx_config.cp; + config.dl_compr_params = tx_config.dl_compr_params; + config.ul_compr_params = tx_config.ul_compr_params; + config.prach_compr_params = tx_config.prach_compr_params; + config.cp = tx_config.cp; + + ether::vlan_frame_params ether_params; + ether_params.eth_type = ether::ECPRI_ETH_TYPE; + ether_params.tci = tx_config.tci_cp; + ether_params.mac_dst_address = tx_config.mac_dst_address; + ether_params.mac_src_address = tx_config.mac_src_address; data_flow_cplane_scheduling_commands_impl_dependencies dependencies; dependencies.logger = &logger; dependencies.ul_cplane_context_repo = std::move(ul_cplane_context_repo); dependencies.frame_pool = std::move(frame_pool); - dependencies.eth_builder = ether::create_vlan_frame_builder(); + dependencies.eth_builder = (tx_config.tci_cp.has_value()) ? ether::create_vlan_frame_builder(ether_params) + : ether::create_frame_builder(ether_params); dependencies.ecpri_builder = ecpri::create_ecpri_packet_builder(); dependencies.cp_builder = (static_compr_header_enabled) ? ofh::create_ofh_control_plane_static_compression_message_builder() @@ -65,18 +68,21 @@ create_data_flow_uplane_data(const transmitter_config& tx_config, data_flow_uplane_downlink_data_impl_config config; config.ru_nof_prbs = get_max_Nprb(bs_channel_bandwidth_to_MHz(tx_config.ru_working_bw), tx_config.scs, srsran::frequency_range::FR1); - config.dl_eaxc = tx_config.dl_eaxc; - config.vlan_params.eth_type = ether::ECPRI_ETH_TYPE; - config.vlan_params.tci = tx_config.tci_up; - config.vlan_params.mac_dst_address = tx_config.mac_dst_address; - config.vlan_params.mac_src_address = tx_config.mac_src_address; - config.compr_params = tx_config.dl_compr_params; - config.cp = tx_config.cp; + config.dl_eaxc = tx_config.dl_eaxc; + config.compr_params = tx_config.dl_compr_params; + config.cp = tx_config.cp; + + ether::vlan_frame_params ether_params; + ether_params.eth_type = ether::ECPRI_ETH_TYPE; + ether_params.tci = tx_config.tci_up; + ether_params.mac_dst_address = tx_config.mac_dst_address; + ether_params.mac_src_address = tx_config.mac_src_address; data_flow_uplane_downlink_data_impl_dependencies dependencies; dependencies.logger = &logger; dependencies.frame_pool = std::move(frame_pool); - dependencies.eth_builder = ether::create_vlan_frame_builder(); + dependencies.eth_builder = (tx_config.tci_up.has_value()) ? ether::create_vlan_frame_builder(ether_params) + : ether::create_frame_builder(ether_params); dependencies.ecpri_builder = ecpri::create_ecpri_packet_builder(); const unsigned nof_prbs = @@ -178,7 +184,9 @@ create_uplink_request_handler(const transmitter_config& static std::shared_ptr create_eth_frame_pool(const transmitter_config& tx_config, srslog::basic_logger& logger) { - auto eth_builder = ether::create_vlan_frame_builder(); + ether::vlan_frame_params ether_params; + auto eth_builder = (tx_config.tci_up || tx_config.tci_cp) ? ether::create_vlan_frame_builder(ether_params) + : ether::create_frame_builder(ether_params); auto ecpri_builder = ecpri::create_ecpri_packet_builder(); std::array, ofh::NOF_COMPRESSION_TYPES_SUPPORTED> compressors; diff --git a/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test.cpp b/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test.cpp index a503ef6a32..b18a840eae 100644 --- a/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test.cpp +++ b/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test.cpp @@ -27,12 +27,34 @@ TEST(vlan_ethernet_frame_builder_impl_test, build_valid_vlan_ethernet_frame_shou params.tci = 2; params.eth_type = 0xaabb; - std::unique_ptr builder = create_vlan_frame_builder(); + std::unique_ptr builder = create_vlan_frame_builder(params); std::copy(packet.begin() + builder->get_header_size().value(), packet.end(), result_packet.begin() + builder->get_header_size().value()); - builder->build_vlan_frame(result_packet, params); + builder->build_frame(result_packet); + + ASSERT_EQ(packet, result_packet); +} + +TEST(ethernet_frame_builder_without_vlan_impl_test, build_valid_ethernet_frame_should_pass) +{ + std::vector packet = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x80, 0x61, 0x5f, 0x0d, 0xdf, 0xaa, 0xaa, 0xbb, 0x00, 0x00, 0x00}; + + std::vector result_packet(packet.size(), 0); + + vlan_frame_params params; + params.mac_dst_address = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; + params.mac_src_address = {0x80, 0x61, 0x5f, 0x0d, 0xdf, 0xaa}; + params.eth_type = 0xaabb; + + std::unique_ptr builder = create_frame_builder(params); + std::copy(packet.begin() + builder->get_header_size().value(), + packet.end(), + result_packet.begin() + builder->get_header_size().value()); + + builder->build_frame(result_packet); ASSERT_EQ(packet, result_packet); } diff --git a/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test_doubles.h b/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test_doubles.h index 43165fd864..c9f7391c32 100644 --- a/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test_doubles.h +++ b/tests/unittests/ofh/ethernet/vlan_ethernet_frame_builder_test_doubles.h @@ -10,28 +10,26 @@ #pragma once -#include "srsran/ofh/ethernet/vlan_ethernet_frame_builder.h" +#include "srsran/ofh/ethernet/ethernet_frame_builder.h" namespace srsran { namespace ether { namespace testing { /// Spy VLAN frame builder implementation. -class vlan_frame_builder_spy : public vlan_frame_builder +class vlan_frame_builder_spy : public frame_builder { bool build_vlan_frame_method_called = false; vlan_frame_params params; public: + explicit vlan_frame_builder_spy(const vlan_frame_params& eth_params) : params(eth_params) {} + // See interface for documentation. units::bytes get_header_size() const override { return units::bytes(18); } // See interface for documentation. - void build_vlan_frame(span buffer, const vlan_frame_params& eth_params) override - { - build_vlan_frame_method_called = true; - params = eth_params; - } + void build_frame(span buffer) override { build_vlan_frame_method_called = true; } /// Returns true if the build VLAN frame has been called, otherwise false. bool has_build_vlan_frame_method_been_called() const { return build_vlan_frame_method_called; } diff --git a/tests/unittests/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_test.cpp b/tests/unittests/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_test.cpp index 49ddeda002..da26576354 100644 --- a/tests/unittests/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_test.cpp +++ b/tests/unittests/ofh/transmitter/ofh_data_flow_cplane_scheduling_commands_test.cpp @@ -102,7 +102,6 @@ class data_flow_cplane_scheduling_commands_impl_fixture : public ::testing::Test data_flow_cplane_scheduling_commands_impl_config config; config.ru_nof_prbs = ru_nof_prbs; - config.vlan_params = vlan_params; config.dl_compr_params = dl_compr_params; config.ul_compr_params = ul_compr_params; config.prach_compr_params = prach_compr_params; @@ -123,7 +122,7 @@ class data_flow_cplane_scheduling_commands_impl_fixture : public ::testing::Test dependencies.cp_builder = std::move(temp); } { - auto temp = std::make_unique(); + auto temp = std::make_unique(vlan_params); vlan_builder = temp.get(); dependencies.eth_builder = std::move(temp); } diff --git a/tests/unittests/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl_test.cpp b/tests/unittests/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl_test.cpp index ef39c978e3..00f37d8b4e 100644 --- a/tests/unittests/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl_test.cpp +++ b/tests/unittests/ofh/transmitter/ofh_data_flow_uplane_downlink_data_impl_test.cpp @@ -98,7 +98,6 @@ class ofh_data_flow_uplane_downlink_data_impl_fixture : public ::testing::TestWi { data_flow_uplane_downlink_data_impl_config config; config.ru_nof_prbs = ru_nof_prbs; - config.vlan_params = vlan_params; config.compr_params = compr_params; return config; @@ -117,7 +116,7 @@ class ofh_data_flow_uplane_downlink_data_impl_fixture : public ::testing::TestWi dependencies.up_builder = std::move(temp); } { - auto temp = std::make_unique(); + auto temp = std::make_unique(vlan_params); vlan_builder = temp.get(); dependencies.eth_builder = std::move(temp); } @@ -228,9 +227,11 @@ TEST(ofh_data_flow_uplane_downlink_data_impl, data_flow_uplane_downlink_data_impl_config config; config.ru_nof_prbs = 273; - config.vlan_params = {{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11}, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x22}, 1, 0xaabb}; config.compr_params = {compression_type::BFP, 9}; + ether::vlan_frame_params vlan_params = { + {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11}, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x22}, 1, 0xaabb}; + data_flow_uplane_downlink_data_impl_dependencies dependencies; dependencies.logger = &srslog::fetch_basic_logger("TEST"); dependencies.compressor_sel = std::make_unique(); @@ -247,7 +248,7 @@ TEST(ofh_data_flow_uplane_downlink_data_impl, dependencies.up_builder = std::move(temp); } { - auto temp = std::make_unique(); + auto temp = std::make_unique(vlan_params); frame_size += temp->get_header_size().value(); dependencies.eth_builder = std::move(temp); } @@ -289,9 +290,11 @@ TEST(ofh_data_flow_uplane_downlink_data_impl, frame_buffer_size_of_nof_prbs_gene data_flow_uplane_downlink_data_impl_config config; config.ru_nof_prbs = 273; - config.vlan_params = {{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11}, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x22}, 1, 0xaabb}; config.compr_params = {compression_type::BFP, 9}; + ether::vlan_frame_params vlan_params = { + {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11}, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x22}, 1, 0xaabb}; + data_flow_uplane_downlink_data_impl_dependencies dependencies; dependencies.logger = &srslog::fetch_basic_logger("TEST"); dependencies.compressor_sel = std::make_unique(); @@ -308,7 +311,7 @@ TEST(ofh_data_flow_uplane_downlink_data_impl, frame_buffer_size_of_nof_prbs_gene dependencies.up_builder = std::move(temp); } { - auto temp = std::make_unique(); + auto temp = std::make_unique(vlan_params); dependencies.eth_builder = std::move(temp); } { From 55a382a082c8102318d9c6fbeb3373b078b71504 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 20 Sep 2024 16:29:47 +0200 Subject: [PATCH 096/174] F1AP: Re-organise public interfaces common to DU and CUCP --- include/srsran/cu_cp/cu_cp_f1c_handler.h | 2 +- include/srsran/du/du_high/du_high.h | 2 +- include/srsran/f1ap/cu_cp/f1ap_cu.h | 4 +-- include/srsran/f1ap/cu_cp/f1ap_cu_factory.h | 1 + .../f1ap/cu_cp/f1ap_cu_ue_context_update.h | 4 +-- include/srsran/f1ap/du/f1ap_du.h | 2 +- include/srsran/f1ap/du/f1ap_du_ue_config.h | 2 +- .../f1ap/du/f1ap_du_ue_context_update.h | 2 +- .../srsran/f1ap/{common => }/f1ap_message.h | 4 +-- include/srsran/f1ap/f1ap_message_handler.h | 27 +++++++++++++++++++ .../f1ap_common.h => f1ap_message_notifier.h} | 15 ++--------- .../f1ap_ue_id.h => f1ap_ue_id_types.h} | 24 ++++++++--------- .../f1ap/gateways/f1c_connection_client.h | 2 +- ...nfig.h => ue_context_management_configs.h} | 11 ++++---- .../du_connection_manager.cpp | 2 +- lib/cu_cp/du_processor/du_processor_factory.h | 2 +- ...blishment_context_modification_routine.cpp | 2 +- .../adapters/f1ap_test_mode_adapter.cpp | 2 +- lib/f1ap/CMakeLists.txt | 4 ++- lib/f1ap/{common => }/asn1_helpers.cpp | 2 +- lib/f1ap/{common => }/asn1_helpers.h | 2 +- lib/f1ap/common/CMakeLists.txt | 10 ------- lib/f1ap/cu_cp/f1ap_asn1_converters.h | 2 +- lib/f1ap/cu_cp/f1ap_asn1_helpers.h | 2 +- lib/f1ap/cu_cp/f1ap_cu_impl.cpp | 8 +++--- lib/f1ap/cu_cp/f1ap_cu_impl.h | 1 + .../cu_cp/procedures/f1_removal_procedure.cpp | 4 +-- .../cu_cp/procedures/f1_removal_procedure.h | 4 +-- .../cu_cp/procedures/f1_setup_procedure.cpp | 4 +-- .../cu_cp/procedures/f1_setup_procedure.h | 4 +-- .../ue_context_modification_procedure.cpp | 4 +-- .../ue_context_modification_procedure.h | 4 +-- .../ue_context_release_procedure.cpp | 2 +- .../procedures/ue_context_release_procedure.h | 4 +-- .../procedures/ue_context_setup_procedure.cpp | 2 +- .../procedures/ue_context_setup_procedure.h | 2 +- .../cu_cp/ue_context/f1ap_cu_ue_context.h | 2 +- lib/f1ap/cu_cp/ue_context/f1ap_ue_ids.h | 4 +-- lib/f1ap/cu_cp/ue_context/f1ap_ue_logger.h | 2 +- lib/f1ap/du/f1ap_du_connection_handler.h | 1 + lib/f1ap/du/f1ap_du_impl.cpp | 6 ++--- .../procedures/f1ap_du_removal_procedure.cpp | 6 ++--- .../du/procedures/f1ap_du_setup_procedure.cpp | 2 +- .../du/procedures/f1ap_du_setup_procedure.h | 3 ++- ...p_du_ue_context_modification_procedure.cpp | 4 +-- .../f1ap_du_ue_context_release_procedure.cpp | 2 +- .../f1ap_du_ue_context_setup_procedure.cpp | 4 +-- .../gnb_cu_configuration_update_procedure.cpp | 3 +-- .../gnb_cu_configuration_update_procedure.h | 2 +- lib/f1ap/du/procedures/proc_logger.h | 2 +- lib/f1ap/du/ue_context/f1ap_du_ue.h | 2 +- lib/f1ap/du/ue_context/f1ap_ue_context.h | 4 +-- lib/f1ap/du/ue_context/f1c_du_bearer_impl.cpp | 2 +- lib/f1ap/du/ue_context/f1c_du_bearer_impl.h | 3 ++- lib/f1ap/du/ue_context/ue_bearer_manager.h | 2 +- lib/f1ap/{common => }/f1ap_asn1_packer.cpp | 2 +- lib/f1ap/{common => }/f1ap_asn1_packer.h | 0 lib/f1ap/{common => }/f1ap_asn1_utils.h | 2 +- .../{common => }/f1ap_common_messages.cpp | 0 lib/f1ap/{common => }/f1ap_common_messages.h | 4 +-- .../gateways/f1c_local_connector_factory.cpp | 2 +- .../gateways/f1c_network_client_factory.cpp | 2 +- .../gateways/f1c_network_server_factory.cpp | 2 +- lib/f1ap/{common => }/log_helpers.cpp | 0 lib/f1ap/{common => }/log_helpers.h | 2 +- lib/f1ap/{common => }/proc_logger.h | 2 +- .../du_high/du_high_many_cells_test.cpp | 2 +- .../integrationtests/du_high/paging_test.cpp | 4 +-- .../test_utils/du_high_env_simulator.h | 2 +- .../f1ap/f1ap_test_message_validators.cpp | 4 +-- .../f1ap/f1ap_test_message_validators.h | 2 +- .../test_doubles/f1ap/f1ap_test_messages.cpp | 2 +- tests/test_doubles/f1ap/f1ap_test_messages.h | 2 +- .../f1ap/f1c_test_local_gateway.h | 2 +- .../cu_cp/cu_cp_connectivity_test.cpp | 2 +- .../cu_cp_initial_context_setup_test.cpp | 2 +- .../cu_cp/cu_cp_inter_du_handover_test.cpp | 4 +-- tests/unittests/cu_cp/cu_cp_paging_test.cpp | 2 +- ...cu_cp_pdu_session_resource_modify_test.cpp | 2 +- ...u_cp_pdu_session_resource_release_test.cpp | 2 +- .../cu_cp_pdu_session_resource_setup_test.cpp | 2 +- .../cu_cp/cu_cp_reestablishment_test.cpp | 2 +- tests/unittests/cu_cp/cu_cp_setup_test.cpp | 2 +- .../cu_cp/cu_cp_test_environment.cpp | 2 +- tests/unittests/cu_cp/cu_cp_test_messages.cpp | 2 +- .../cu_cp/cu_cp_ue_context_release_test.cpp | 4 +-- .../cu_cp/du_processor_test_messages.cpp | 4 +-- .../cu_cp/du_processor_test_messages.h | 2 +- .../unittests/cu_cp/test_doubles/dummy_du.cpp | 2 +- .../unittests/cu_cp/test_doubles/mock_du.cpp | 4 +-- tests/unittests/cu_cp/test_doubles/mock_du.h | 4 +-- .../f1ap/common/f1ap_asn1_helpers_test.cpp | 2 +- .../f1ap/common/f1ap_asn1_packer_test.cpp | 2 +- .../f1ap/common/f1ap_cu_test_messages.cpp | 2 +- .../f1ap/common/f1ap_cu_test_messages.h | 2 +- .../f1ap/common/f1ap_du_test_messages.cpp | 2 +- .../f1ap/common/f1ap_du_test_messages.h | 4 +-- tests/unittests/f1ap/common/test_helpers.h | 5 ++-- tests/unittests/f1ap/cu_cp/f1ap_cu_test.cpp | 2 +- .../f1ap/cu_cp/f1ap_cu_test_helpers.h | 2 +- .../f1ap/cu_cp/f1ap_cu_ue_context_test.cpp | 2 +- .../f1ap/du/f1ap_du_setup_procedure_test.cpp | 2 +- .../f1ap/du/f1ap_du_test_helpers.cpp | 2 +- .../unittests/f1ap/du/f1ap_du_test_helpers.h | 3 +-- .../f1ap/gateways/f1c_gateway_test.cpp | 4 +-- 105 files changed, 181 insertions(+), 168 deletions(-) rename include/srsran/f1ap/{common => }/f1ap_message.h (78%) create mode 100644 include/srsran/f1ap/f1ap_message_handler.h rename include/srsran/f1ap/{common/f1ap_common.h => f1ap_message_notifier.h} (52%) rename include/srsran/f1ap/{common/f1ap_ue_id.h => f1ap_ue_id_types.h} (59%) rename include/srsran/f1ap/{common/ue_context_config.h => ue_context_management_configs.h} (93%) rename lib/f1ap/{common => }/asn1_helpers.cpp (99%) rename lib/f1ap/{common => }/asn1_helpers.h (98%) delete mode 100644 lib/f1ap/common/CMakeLists.txt rename lib/f1ap/{common => }/f1ap_asn1_packer.cpp (96%) rename lib/f1ap/{common => }/f1ap_asn1_packer.h (100%) rename lib/f1ap/{common => }/f1ap_asn1_utils.h (99%) rename lib/f1ap/{common => }/f1ap_common_messages.cpp (100%) rename lib/f1ap/{common => }/f1ap_common_messages.h (89%) rename lib/f1ap/{common => }/log_helpers.cpp (100%) rename lib/f1ap/{common => }/log_helpers.h (97%) rename lib/f1ap/{common => }/proc_logger.h (97%) diff --git a/include/srsran/cu_cp/cu_cp_f1c_handler.h b/include/srsran/cu_cp/cu_cp_f1c_handler.h index 0929b3f935..f25729dddb 100644 --- a/include/srsran/cu_cp/cu_cp_f1c_handler.h +++ b/include/srsran/cu_cp/cu_cp_f1c_handler.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include namespace srsran { diff --git a/include/srsran/du/du_high/du_high.h b/include/srsran/du/du_high/du_high.h index 00a22f9635..4b215dfca8 100644 --- a/include/srsran/du/du_high/du_high.h +++ b/include/srsran/du/du_high/du_high.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/f1ap_message_handler.h" #include "srsran/mac/mac_cell_control_information_handler.h" #include "srsran/mac/mac_cell_rach_handler.h" #include "srsran/mac/mac_cell_slot_handler.h" diff --git a/include/srsran/f1ap/cu_cp/f1ap_cu.h b/include/srsran/f1ap/cu_cp/f1ap_cu.h index 3eff15b5d8..990d2497ff 100644 --- a/include/srsran/f1ap/cu_cp/f1ap_cu.h +++ b/include/srsran/f1ap/cu_cp/f1ap_cu.h @@ -16,9 +16,9 @@ #include "srsran/adt/expected.h" #include "srsran/cu_cp/cu_cp_types.h" #include "srsran/cu_cp/cu_cp_ue_messages.h" -#include "srsran/f1ap/common/f1ap_common.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/cu_cp/f1ap_du_context.h" +#include "srsran/f1ap/f1ap_message_handler.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/lcid.h" #include "srsran/support/async/async_task.h" diff --git a/include/srsran/f1ap/cu_cp/f1ap_cu_factory.h b/include/srsran/f1ap/cu_cp/f1ap_cu_factory.h index f6e7fc46be..8caf1f4b3b 100644 --- a/include/srsran/f1ap/cu_cp/f1ap_cu_factory.h +++ b/include/srsran/f1ap/cu_cp/f1ap_cu_factory.h @@ -12,6 +12,7 @@ #include "f1ap_configuration.h" #include "f1ap_cu.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/support/executors/task_executor.h" #include diff --git a/include/srsran/f1ap/cu_cp/f1ap_cu_ue_context_update.h b/include/srsran/f1ap/cu_cp/f1ap_cu_ue_context_update.h index 294233990a..55c4e5b3ca 100644 --- a/include/srsran/f1ap/cu_cp/f1ap_cu_ue_context_update.h +++ b/include/srsran/f1ap/cu_cp/f1ap_cu_ue_context_update.h @@ -11,8 +11,8 @@ #pragma once #include "srsran/cu_cp/cu_cp_types.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" -#include "srsran/f1ap/common/ue_context_config.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" +#include "srsran/f1ap/ue_context_management_configs.h" #include "srsran/ran/cause/f1ap_cause.h" #include "srsran/ran/cu_types.h" #include "srsran/ran/lcid.h" diff --git a/include/srsran/f1ap/du/f1ap_du.h b/include/srsran/f1ap/du/f1ap_du.h index 27113d9ae3..e3faee621f 100644 --- a/include/srsran/f1ap/du/f1ap_du.h +++ b/include/srsran/f1ap/du/f1ap_du.h @@ -13,9 +13,9 @@ #include "f1ap_du_ue_config.h" #include "f1c_bearer.h" #include "srsran/adt/expected.h" -#include "srsran/f1ap/common/f1ap_common.h" #include "srsran/f1ap/du/f1ap_du_connection_manager.h" #include "srsran/f1ap/du/f1ap_du_ue_context_update.h" +#include "srsran/f1ap/f1ap_message_handler.h" #include "srsran/f1u/du/f1u_bearer.h" #include "srsran/mac/mac_paging_information_handler.h" #include "srsran/ran/du_types.h" diff --git a/include/srsran/f1ap/du/f1ap_du_ue_config.h b/include/srsran/f1ap/du/f1ap_du_ue_config.h index c4b86f3740..2e485b4143 100644 --- a/include/srsran/f1ap/du/f1ap_du_ue_config.h +++ b/include/srsran/f1ap/du/f1ap_du_ue_config.h @@ -11,9 +11,9 @@ #pragma once #include "srsran/adt/optional.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/du/f1c_bearer.h" #include "srsran/f1ap/du/f1c_rx_sdu_notifier.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/du_types.h" #include "srsran/ran/lcid.h" #include "srsran/ran/rnti.h" diff --git a/include/srsran/f1ap/du/f1ap_du_ue_context_update.h b/include/srsran/f1ap/du/f1ap_du_ue_context_update.h index ac877004ab..f685dfc07f 100644 --- a/include/srsran/f1ap/du/f1ap_du_ue_context_update.h +++ b/include/srsran/f1ap/du/f1ap_du_ue_context_update.h @@ -12,7 +12,7 @@ #include "srsran/adt/byte_buffer.h" #include "srsran/adt/optional.h" -#include "srsran/f1ap/common/ue_context_config.h" +#include "srsran/f1ap/ue_context_management_configs.h" #include "srsran/pdcp/pdcp_sn_size.h" #include "srsran/ran/du_types.h" #include "srsran/ran/qos/five_qi.h" diff --git a/include/srsran/f1ap/common/f1ap_message.h b/include/srsran/f1ap/f1ap_message.h similarity index 78% rename from include/srsran/f1ap/common/f1ap_message.h rename to include/srsran/f1ap/f1ap_message.h index d8c4ab45c2..2fbaa18023 100644 --- a/include/srsran/f1ap/common/f1ap_message.h +++ b/include/srsran/f1ap/f1ap_message.h @@ -14,9 +14,9 @@ namespace srsran { -/// \brief F1AP message transferred between a CU-CP and a DU. +/// F1AP message definition which is transferred between a CU-CP and a DU. struct f1ap_message { asn1::f1ap::f1ap_pdu_c pdu; }; -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/include/srsran/f1ap/f1ap_message_handler.h b/include/srsran/f1ap/f1ap_message_handler.h new file mode 100644 index 0000000000..4ca5987a0e --- /dev/null +++ b/include/srsran/f1ap/f1ap_message_handler.h @@ -0,0 +1,27 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +namespace srsran { + +struct f1ap_message; + +/// Handles incoming F1AP messages. +class f1ap_message_handler +{ +public: + virtual ~f1ap_message_handler() = default; + + /// Handles the given F1AP message. + virtual void handle_message(const f1ap_message& msg) = 0; +}; + +} // namespace srsran diff --git a/include/srsran/f1ap/common/f1ap_common.h b/include/srsran/f1ap/f1ap_message_notifier.h similarity index 52% rename from include/srsran/f1ap/common/f1ap_common.h rename to include/srsran/f1ap/f1ap_message_notifier.h index 109ebdd705..968120c33c 100644 --- a/include/srsran/f1ap/common/f1ap_common.h +++ b/include/srsran/f1ap/f1ap_message_notifier.h @@ -12,26 +12,15 @@ namespace srsran { -// Forward declaration. struct f1ap_message; -/// Interface for the handler of received F1AP PDUs. -class f1ap_message_handler -{ -public: - virtual ~f1ap_message_handler() = default; - - /// Handle the incoming F1AP message. - virtual void handle_message(const f1ap_message& msg) = 0; -}; - -/// Notifier interface used to forward F1AP PDUs to either the CU-CP or DU. +/// Notifier interface used to notify outgoing F1AP messages. class f1ap_message_notifier { public: virtual ~f1ap_message_notifier() = default; - /// This callback is invoked on each forwarded F1AP message. + /// This callback is invoked on each outgoing F1AP message. virtual void on_new_message(const f1ap_message& msg) = 0; }; diff --git a/include/srsran/f1ap/common/f1ap_ue_id.h b/include/srsran/f1ap/f1ap_ue_id_types.h similarity index 59% rename from include/srsran/f1ap/common/f1ap_ue_id.h rename to include/srsran/f1ap/f1ap_ue_id_types.h index c17a79df49..2805203e58 100644 --- a/include/srsran/f1ap/common/f1ap_ue_id.h +++ b/include/srsran/f1ap/f1ap_ue_id_types.h @@ -11,39 +11,39 @@ #pragma once #include -#include -#include namespace srsran { /// \brief GNB-CU-UE-F1AP-ID used to identify the UE in the F1AP-CU. -/// \remark See TS 38.473 Section 9.3.1.4: GNB-CU-UE-F1AP-ID valid values: (0..2^32-1) -static constexpr uint64_t MAX_NOF_CU_F1AP_UES = ((uint64_t)1 << 32); +/// \remark See TS 38.473 Section 9.3.1.4: GNB-CU-UE-F1AP-ID valid values: (0..2^32-1). +constexpr uint64_t MAX_NOF_CU_F1AP_UES = uint64_t(1) << 32; enum class gnb_cu_ue_f1ap_id_t : uint64_t { min = 0, max = MAX_NOF_CU_F1AP_UES - 1, invalid = 0x1ffffffff }; -constexpr inline uint64_t gnb_cu_ue_f1ap_id_to_uint(gnb_cu_ue_f1ap_id_t id) +/// Converts a GNB-CU-UE-F1AP-ID to an integer. +constexpr uint64_t gnb_cu_ue_f1ap_id_to_uint(gnb_cu_ue_f1ap_id_t id) { return static_cast(id); } -/// Convert integer to GNB-CU-UE-F1AP-ID type. -constexpr inline gnb_cu_ue_f1ap_id_t int_to_gnb_cu_ue_f1ap_id(uint64_t idx) +/// Converts an integer to a GNB-CU-UE-F1AP-ID type. +constexpr gnb_cu_ue_f1ap_id_t int_to_gnb_cu_ue_f1ap_id(uint64_t idx) { return static_cast(idx); } /// \brief GNB-DU-UE-F1AP-ID used to identify the UE in the F1AP-DU. -/// \remark See TS 38.473 Section 9.3.1.5: GNB-DU-UE-F1AP-ID valid values: (0..2^32-1) -static constexpr uint64_t MAX_NOF_DU_F1AP_UES = (static_cast(1) << static_cast(32U)); +/// \remark See TS 38.473 Section 9.3.1.5: GNB-DU-UE-F1AP-ID valid values: (0..2^32-1). +constexpr uint64_t MAX_NOF_DU_F1AP_UES = uint64_t(1) << 32; enum class gnb_du_ue_f1ap_id_t : uint64_t { min = 0, max = MAX_NOF_DU_F1AP_UES - 1, invalid = 0x1ffffffff }; -constexpr inline uint64_t gnb_du_ue_f1ap_id_to_uint(gnb_du_ue_f1ap_id_t id) +/// Converts a GNB-DU-UE-F1AP-ID to an integer. +constexpr uint64_t gnb_du_ue_f1ap_id_to_uint(gnb_du_ue_f1ap_id_t id) { return static_cast(id); } -/// Convert integer to GNB-DU-UE-F1AP-ID type. -constexpr inline gnb_du_ue_f1ap_id_t int_to_gnb_du_ue_f1ap_id(uint64_t idx) +/// Convert an integer to a GNB-DU-UE-F1AP-ID type. +constexpr gnb_du_ue_f1ap_id_t int_to_gnb_du_ue_f1ap_id(uint64_t idx) { return static_cast(idx); } diff --git a/include/srsran/f1ap/gateways/f1c_connection_client.h b/include/srsran/f1ap/gateways/f1c_connection_client.h index 58e83fba4e..8dde15e940 100644 --- a/include/srsran/f1ap/gateways/f1c_connection_client.h +++ b/include/srsran/f1ap/gateways/f1c_connection_client.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include namespace srsran { diff --git a/include/srsran/f1ap/common/ue_context_config.h b/include/srsran/f1ap/ue_context_management_configs.h similarity index 93% rename from include/srsran/f1ap/common/ue_context_config.h rename to include/srsran/f1ap/ue_context_management_configs.h index e37432db4c..6917cb4b24 100644 --- a/include/srsran/f1ap/common/ue_context_config.h +++ b/include/srsran/f1ap/ue_context_management_configs.h @@ -29,11 +29,11 @@ struct f1ap_srb_to_setup { /// Parameters of a failed SRB setup in the DU UE context. struct f1ap_srb_failed_to_setup { srb_id_t srb_id = srb_id_t::nulltype; - /// Reason for the failure + /// Reason for the failure. std::optional cause; }; -/// \brief Used to activate notification control for a given DRB. +/// Used to activate notification control for a given DRB. enum class drb_notification_control { active = 0, not_active }; struct flow_mapped_to_drb { @@ -44,7 +44,8 @@ struct flow_mapped_to_drb { struct f1ap_drb_info { qos_flow_level_qos_parameters drb_qos; s_nssai_t s_nssai; - /// \brief Sets whether notification control is active. + /// \brief Establishes whether notification control is active. + /// /// [TS 38.473 8.3.1.2] If the Notification Control IE is included in the DRB to Be Setup List IE and it is set to /// active, the gNB-DU shall, if supported, monitor the QoS of the DRB and notify the gNB-CU if the QoS cannot be /// fulfilled any longer or if the QoS can be fulfilled again. The Notification Control IE can only be applied to GBR @@ -92,8 +93,8 @@ struct f1ap_drb_setupmod { struct f1ap_drb_failed_to_setupmod { /// DRB-Id of the failed to setup/modify DRB. drb_id_t drb_id = drb_id_t::invalid; - /// Reason for the failure + /// Reason for the failure. std::optional cause; }; -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp b/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp index 61b52f6c4e..b3b0fb4f35 100644 --- a/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp +++ b/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp @@ -10,7 +10,7 @@ #include "du_connection_manager.h" #include "../du_processor/du_processor_repository.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/support/executors/sync_task_executor.h" #include diff --git a/lib/cu_cp/du_processor/du_processor_factory.h b/lib/cu_cp/du_processor/du_processor_factory.h index 70b55770f1..6288b73cd0 100644 --- a/lib/cu_cp/du_processor/du_processor_factory.h +++ b/lib/cu_cp/du_processor/du_processor_factory.h @@ -13,7 +13,7 @@ #include "../ue_manager/ue_manager_impl.h" #include "du_processor.h" #include "du_processor_config.h" -#include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/rrc/rrc_ue.h" #include "srsran/support/executors/task_executor.h" #include diff --git a/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp b/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp index 7042023c45..2d8254305f 100644 --- a/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp +++ b/lib/cu_cp/routines/reestablishment_context_modification_routine.cpp @@ -11,7 +11,7 @@ #include "reestablishment_context_modification_routine.h" #include "pdu_session_routine_helpers.h" #include "srsran/e1ap/cu_cp/e1ap_cu_cp_bearer_context_update.h" -#include "srsran/f1ap/common/ue_context_config.h" +#include "srsran/f1ap/ue_context_management_configs.h" using namespace srsran; using namespace srsran::srs_cu_cp; diff --git a/lib/du/du_high/adapters/f1ap_test_mode_adapter.cpp b/lib/du/du_high/adapters/f1ap_test_mode_adapter.cpp index 8a94237e9b..c84d74563b 100644 --- a/lib/du/du_high/adapters/f1ap_test_mode_adapter.cpp +++ b/lib/du/du_high/adapters/f1ap_test_mode_adapter.cpp @@ -11,8 +11,8 @@ #include "f1ap_test_mode_adapter.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" -#include "srsran/f1ap/common/f1ap_message.h" #include "srsran/f1ap/du/f1ap_du_factory.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srs_du; diff --git a/lib/f1ap/CMakeLists.txt b/lib/f1ap/CMakeLists.txt index a345bc63dd..60b262c92c 100644 --- a/lib/f1ap/CMakeLists.txt +++ b/lib/f1ap/CMakeLists.txt @@ -6,7 +6,9 @@ # the distribution. # -add_subdirectory(common) add_subdirectory(cu_cp) add_subdirectory(du) add_subdirectory(gateways) + +add_library(srsran_f1ap_common f1ap_common_messages.cpp asn1_helpers.cpp f1ap_asn1_packer.cpp log_helpers.cpp) +target_link_libraries(srsran_f1ap_common f1ap_asn1) diff --git a/lib/f1ap/common/asn1_helpers.cpp b/lib/f1ap/asn1_helpers.cpp similarity index 99% rename from lib/f1ap/common/asn1_helpers.cpp rename to lib/f1ap/asn1_helpers.cpp index ad188002e4..a65c7aba4d 100644 --- a/lib/f1ap/common/asn1_helpers.cpp +++ b/lib/f1ap/asn1_helpers.cpp @@ -9,7 +9,7 @@ */ #include "asn1_helpers.h" -#include "../cu_cp/f1ap_asn1_converters.h" +#include "cu_cp/f1ap_asn1_converters.h" #include "srsran/asn1/f1ap/common.h" using namespace srsran; diff --git a/lib/f1ap/common/asn1_helpers.h b/lib/f1ap/asn1_helpers.h similarity index 98% rename from lib/f1ap/common/asn1_helpers.h rename to lib/f1ap/asn1_helpers.h index 66df6239fb..cee5a03f1c 100644 --- a/lib/f1ap/common/asn1_helpers.h +++ b/lib/f1ap/asn1_helpers.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/asn1/f1ap/f1ap_pdu_items.h" -#include "srsran/f1ap/common/ue_context_config.h" +#include "srsran/f1ap/ue_context_management_configs.h" #include "srsran/pdcp/pdcp_sn_size.h" #include "srsran/ran/nr_cgi.h" diff --git a/lib/f1ap/common/CMakeLists.txt b/lib/f1ap/common/CMakeLists.txt deleted file mode 100644 index 2f75c199fe..0000000000 --- a/lib/f1ap/common/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright 2021-2024 Software Radio Systems Limited -# -# By using this file, you agree to the terms and conditions set -# forth in the LICENSE file which can be found at the top level of -# the distribution. -# - -add_library(srsran_f1ap_common f1ap_common_messages.cpp asn1_helpers.cpp f1ap_asn1_packer.cpp log_helpers.cpp) -target_link_libraries(srsran_f1ap_common f1ap_asn1) diff --git a/lib/f1ap/cu_cp/f1ap_asn1_converters.h b/lib/f1ap/cu_cp/f1ap_asn1_converters.h index 3d98e09f90..5720dfb707 100644 --- a/lib/f1ap/cu_cp/f1ap_asn1_converters.h +++ b/lib/f1ap/cu_cp/f1ap_asn1_converters.h @@ -10,7 +10,7 @@ #pragma once -#include "../common/asn1_helpers.h" +#include "../asn1_helpers.h" #include "srsran/adt/optional.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_ies.h" diff --git a/lib/f1ap/cu_cp/f1ap_asn1_helpers.h b/lib/f1ap/cu_cp/f1ap_asn1_helpers.h index 7afac55779..2c639d1bc5 100644 --- a/lib/f1ap/cu_cp/f1ap_asn1_helpers.h +++ b/lib/f1ap/cu_cp/f1ap_asn1_helpers.h @@ -10,7 +10,7 @@ #pragma once -#include "../common/asn1_helpers.h" +#include "../asn1_helpers.h" #include "f1ap_asn1_converters.h" #include "srsran/asn1/asn1_utils.h" #include "srsran/asn1/f1ap/f1ap.h" diff --git a/lib/f1ap/cu_cp/f1ap_cu_impl.cpp b/lib/f1ap/cu_cp/f1ap_cu_impl.cpp index dccac4a495..4f1a813d3e 100644 --- a/lib/f1ap/cu_cp/f1ap_cu_impl.cpp +++ b/lib/f1ap/cu_cp/f1ap_cu_impl.cpp @@ -9,10 +9,10 @@ */ #include "f1ap_cu_impl.h" -#include "../common/asn1_helpers.h" -#include "../common/f1ap_asn1_utils.h" -#include "../common/log_helpers.h" +#include "asn1_helpers.h" #include "f1ap_asn1_helpers.h" +#include "f1ap_asn1_utils.h" +#include "log_helpers.h" #include "procedures/f1_removal_procedure.h" #include "procedures/f1_setup_procedure.h" #include "procedures/f1ap_stop_procedure.h" @@ -21,7 +21,7 @@ #include "procedures/ue_context_setup_procedure.h" #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/cu_cp/cu_cp_types.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace asn1::f1ap; diff --git a/lib/f1ap/cu_cp/f1ap_cu_impl.h b/lib/f1ap/cu_cp/f1ap_cu_impl.h index 4f75d21c54..73304f461b 100644 --- a/lib/f1ap/cu_cp/f1ap_cu_impl.h +++ b/lib/f1ap/cu_cp/f1ap_cu_impl.h @@ -14,6 +14,7 @@ #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/f1ap/cu_cp/f1ap_configuration.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/support/executors/task_executor.h" #include diff --git a/lib/f1ap/cu_cp/procedures/f1_removal_procedure.cpp b/lib/f1ap/cu_cp/procedures/f1_removal_procedure.cpp index a93d6eb8fb..78c723c284 100644 --- a/lib/f1ap/cu_cp/procedures/f1_removal_procedure.cpp +++ b/lib/f1ap/cu_cp/procedures/f1_removal_procedure.cpp @@ -12,8 +12,8 @@ #include "../ue_context/f1ap_cu_ue_context.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srs_cu_cp; @@ -80,4 +80,4 @@ void f1_removal_procedure::send_f1_removal_response() asn1::f1ap::f1_removal_resp_s& rem = resp.pdu.successful_outcome().value.f1_removal_resp(); rem->transaction_id = (*request)[0]->transaction_id(); pdu_notifier.on_new_message(resp); -} \ No newline at end of file +} diff --git a/lib/f1ap/cu_cp/procedures/f1_removal_procedure.h b/lib/f1ap/cu_cp/procedures/f1_removal_procedure.h index 3d47300e9f..ad5047815f 100644 --- a/lib/f1ap/cu_cp/procedures/f1_removal_procedure.h +++ b/lib/f1ap/cu_cp/procedures/f1_removal_procedure.h @@ -12,7 +12,7 @@ #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/cu_cp/cu_cp_types.h" -#include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/support/async/async_task.h" namespace srsran { @@ -46,4 +46,4 @@ class f1_removal_procedure }; } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/f1ap/cu_cp/procedures/f1_setup_procedure.cpp b/lib/f1ap/cu_cp/procedures/f1_setup_procedure.cpp index 16a3958ffa..507fa7e51e 100644 --- a/lib/f1ap/cu_cp/procedures/f1_setup_procedure.cpp +++ b/lib/f1ap/cu_cp/procedures/f1_setup_procedure.cpp @@ -9,13 +9,13 @@ */ #include "f1_setup_procedure.h" -#include "../../common/asn1_helpers.h" #include "../f1ap_asn1_converters.h" +#include "asn1_helpers.h" #include "srsran/adt/expected.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" #include "srsran/f1ap/cu_cp/du_setup_notifier.h" #include "srsran/f1ap/cu_cp/f1ap_du_context.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/bcd_helper.h" #include "srsran/ran/cause/f1ap_cause.h" diff --git a/lib/f1ap/cu_cp/procedures/f1_setup_procedure.h b/lib/f1ap/cu_cp/procedures/f1_setup_procedure.h index d7181a6e07..4d3ca4ed65 100644 --- a/lib/f1ap/cu_cp/procedures/f1_setup_procedure.h +++ b/lib/f1ap/cu_cp/procedures/f1_setup_procedure.h @@ -11,8 +11,8 @@ #pragma once #include "srsran/asn1/f1ap/f1ap.h" -#include "srsran/f1ap/common/f1ap_common.h" #include "srsran/f1ap/cu_cp/du_setup_notifier.h" +#include "srsran/f1ap/f1ap_message_notifier.h" namespace srsran { namespace srs_cu_cp { @@ -40,4 +40,4 @@ void handle_f1_setup_procedure(const asn1::f1ap::f1_setup_request_s& request, srslog::basic_logger& logger); } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.cpp b/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.cpp index 562487d14b..5598255896 100644 --- a/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.cpp +++ b/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.cpp @@ -9,9 +9,9 @@ */ #include "ue_context_modification_procedure.h" -#include "../../common/asn1_helpers.h" #include "../f1ap_asn1_converters.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "asn1_helpers.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/cause/ngap_cause.h" using namespace srsran; diff --git a/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.h b/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.h index eeb2bf2c50..cb2d016b1a 100644 --- a/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.h +++ b/lib/f1ap/cu_cp/procedures/ue_context_modification_procedure.h @@ -10,10 +10,10 @@ #pragma once -#include "../../common/f1ap_asn1_utils.h" #include "../f1ap_cu_impl.h" #include "../ue_context/f1ap_cu_ue_context.h" #include "cu_cp/ue_context/f1ap_cu_ue_transaction_manager.h" +#include "f1ap_asn1_utils.h" #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" #include "srsran/support/async/async_task.h" @@ -51,4 +51,4 @@ class ue_context_modification_procedure }; } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.cpp b/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.cpp index c89b1b3199..18dbc964d1 100644 --- a/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.cpp +++ b/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.cpp @@ -10,7 +10,7 @@ #include "ue_context_release_procedure.h" #include "../f1ap_asn1_converters.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/lcid.h" #include "srsran/support/srsran_assert.h" diff --git a/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.h b/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.h index 14eb087838..927f9259f8 100644 --- a/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.h +++ b/lib/f1ap/cu_cp/procedures/ue_context_release_procedure.h @@ -12,8 +12,8 @@ #include "../f1ap_cu_impl.h" #include "../ue_context/f1ap_cu_ue_context.h" -#include "common/f1ap_asn1_utils.h" #include "cu_cp/ue_context/f1ap_cu_ue_transaction_manager.h" +#include "f1ap_asn1_utils.h" #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" #include "srsran/support/async/async_task.h" @@ -50,4 +50,4 @@ class ue_context_release_procedure }; } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.cpp b/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.cpp index 4dfc915797..2240221eae 100644 --- a/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.cpp +++ b/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.cpp @@ -10,7 +10,7 @@ #include "ue_context_setup_procedure.h" #include "../f1ap_asn1_converters.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srsran::srs_cu_cp; diff --git a/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.h b/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.h index d4741f56b0..cb701d63c3 100644 --- a/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.h +++ b/lib/f1ap/cu_cp/procedures/ue_context_setup_procedure.h @@ -11,8 +11,8 @@ #pragma once #include "../f1ap_cu_impl.h" -#include "common/f1ap_asn1_utils.h" #include "cu_cp/ue_context/f1ap_cu_ue_transaction_manager.h" +#include "f1ap_asn1_utils.h" #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/f1ap/cu_cp/f1ap_configuration.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" diff --git a/lib/f1ap/cu_cp/ue_context/f1ap_cu_ue_context.h b/lib/f1ap/cu_cp/ue_context/f1ap_cu_ue_context.h index b4424478c0..bc35f6e313 100644 --- a/lib/f1ap/cu_cp/ue_context/f1ap_cu_ue_context.h +++ b/lib/f1ap/cu_cp/ue_context/f1ap_cu_ue_context.h @@ -12,8 +12,8 @@ #include "f1ap_cu_ue_transaction_manager.h" #include "f1ap_ue_logger.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include namespace srsran { diff --git a/lib/f1ap/cu_cp/ue_context/f1ap_ue_ids.h b/lib/f1ap/cu_cp/ue_context/f1ap_ue_ids.h index 943dc52306..65644530d8 100644 --- a/lib/f1ap/cu_cp/ue_context/f1ap_ue_ids.h +++ b/lib/f1ap/cu_cp/ue_context/f1ap_ue_ids.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/cu_cp/cu_cp_types.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" namespace srsran { namespace srs_cu_cp { @@ -24,4 +24,4 @@ struct f1ap_ue_ids { }; } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/f1ap/cu_cp/ue_context/f1ap_ue_logger.h b/lib/f1ap/cu_cp/ue_context/f1ap_ue_logger.h index 8e8bad1266..5a77d7cfca 100644 --- a/lib/f1ap/cu_cp/ue_context/f1ap_ue_logger.h +++ b/lib/f1ap/cu_cp/ue_context/f1ap_ue_logger.h @@ -9,7 +9,7 @@ */ #pragma once -#include "../../common/proc_logger.h" +#include "../../proc_logger.h" #include "f1ap_ue_ids.h" #include "srsran/support/prefixed_logger.h" diff --git a/lib/f1ap/du/f1ap_du_connection_handler.h b/lib/f1ap/du/f1ap_du_connection_handler.h index 6e03518ef0..a977f76974 100644 --- a/lib/f1ap/du/f1ap_du_connection_handler.h +++ b/lib/f1ap/du/f1ap_du_connection_handler.h @@ -11,6 +11,7 @@ #pragma once #include "srsran/f1ap/du/f1ap_du_connection_manager.h" +#include "srsran/f1ap/f1ap_message_handler.h" #include "srsran/f1ap/gateways/f1c_connection_client.h" #include "srsran/srslog/logger.h" #include "srsran/support/async/manual_event.h" diff --git a/lib/f1ap/du/f1ap_du_impl.cpp b/lib/f1ap/du/f1ap_du_impl.cpp index 1ba047f263..0983d46f84 100644 --- a/lib/f1ap/du/f1ap_du_impl.cpp +++ b/lib/f1ap/du/f1ap_du_impl.cpp @@ -9,9 +9,9 @@ */ #include "f1ap_du_impl.h" -#include "../common/asn1_helpers.h" -#include "../common/log_helpers.h" +#include "asn1_helpers.h" #include "f1ap_du_connection_handler.h" +#include "log_helpers.h" #include "procedures/f1ap_du_removal_procedure.h" #include "procedures/f1ap_du_setup_procedure.h" #include "procedures/f1ap_du_ue_context_release_procedure.h" @@ -20,7 +20,7 @@ #include "ue_context/f1ap_du_ue_config_update.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/f1ap/gateways/f1c_connection_client.h" #include "srsran/ran/nr_cgi.h" #include "srsran/support/async/event_signal.h" diff --git a/lib/f1ap/du/procedures/f1ap_du_removal_procedure.cpp b/lib/f1ap/du/procedures/f1ap_du_removal_procedure.cpp index 76d6ec6d2b..43e0e1aac0 100644 --- a/lib/f1ap/du/procedures/f1ap_du_removal_procedure.cpp +++ b/lib/f1ap/du/procedures/f1ap_du_removal_procedure.cpp @@ -9,10 +9,10 @@ */ #include "f1ap_du_removal_procedure.h" -#include "../../common/f1ap_common_messages.h" +#include "../../f1ap_common_messages.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srs_du; @@ -112,4 +112,4 @@ void f1ap_du_removal_procedure::handle_f1_removal_response() // What else can we do? logger.warning("{}: Forcing shutdown of F1 TNL association after F1 Removal Failure", name()); } -} \ No newline at end of file +} diff --git a/lib/f1ap/du/procedures/f1ap_du_setup_procedure.cpp b/lib/f1ap/du/procedures/f1ap_du_setup_procedure.cpp index a69f3d7657..c665f2ebb6 100644 --- a/lib/f1ap/du/procedures/f1ap_du_setup_procedure.cpp +++ b/lib/f1ap/du/procedures/f1ap_du_setup_procedure.cpp @@ -11,7 +11,7 @@ #include "f1ap_du_setup_procedure.h" #include "../f1ap_du_context.h" #include "srsran/asn1/f1ap/common.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/band_helper.h" #include "srsran/ran/bcd_helper.h" #include "srsran/support/async/async_timer.h" diff --git a/lib/f1ap/du/procedures/f1ap_du_setup_procedure.h b/lib/f1ap/du/procedures/f1ap_du_setup_procedure.h index 67ce84de1e..ac419ddfca 100644 --- a/lib/f1ap/du/procedures/f1ap_du_setup_procedure.h +++ b/lib/f1ap/du/procedures/f1ap_du_setup_procedure.h @@ -10,9 +10,10 @@ #pragma once -#include "../../common/f1ap_asn1_utils.h" +#include "../../f1ap_asn1_utils.h" #include "f1ap_du_event_manager.h" #include "srsran/f1ap/du/f1ap_du.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/support/async/async_task.h" namespace srsran { diff --git a/lib/f1ap/du/procedures/f1ap_du_ue_context_modification_procedure.cpp b/lib/f1ap/du/procedures/f1ap_du_ue_context_modification_procedure.cpp index d63c0c61b5..3fcba32f72 100644 --- a/lib/f1ap/du/procedures/f1ap_du_ue_context_modification_procedure.cpp +++ b/lib/f1ap/du/procedures/f1ap_du_ue_context_modification_procedure.cpp @@ -9,9 +9,9 @@ */ #include "f1ap_du_ue_context_modification_procedure.h" -#include "../../common/asn1_helpers.h" +#include "../../asn1_helpers.h" #include "srsran/asn1/f1ap/common.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srs_du; diff --git a/lib/f1ap/du/procedures/f1ap_du_ue_context_release_procedure.cpp b/lib/f1ap/du/procedures/f1ap_du_ue_context_release_procedure.cpp index e6c7ea8dba..329048baba 100644 --- a/lib/f1ap/du/procedures/f1ap_du_ue_context_release_procedure.cpp +++ b/lib/f1ap/du/procedures/f1ap_du_ue_context_release_procedure.cpp @@ -11,7 +11,7 @@ #include "f1ap_du_ue_context_release_procedure.h" #include "proc_logger.h" #include "srsran/asn1/f1ap/common.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/support/async/async_no_op_task.h" #include "srsran/support/async/async_timer.h" diff --git a/lib/f1ap/du/procedures/f1ap_du_ue_context_setup_procedure.cpp b/lib/f1ap/du/procedures/f1ap_du_ue_context_setup_procedure.cpp index e37e8a99f7..1c6f4edcb5 100644 --- a/lib/f1ap/du/procedures/f1ap_du_ue_context_setup_procedure.cpp +++ b/lib/f1ap/du/procedures/f1ap_du_ue_context_setup_procedure.cpp @@ -9,11 +9,11 @@ */ #include "f1ap_du_ue_context_setup_procedure.h" -#include "../../common/asn1_helpers.h" +#include "../../asn1_helpers.h" #include "../ue_context/f1ap_du_ue_manager.h" #include "proc_logger.h" #include "srsran/asn1/f1ap/common.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/support/async/async_no_op_task.h" using namespace srsran; diff --git a/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.cpp b/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.cpp index f97577c584..f3009bc74c 100644 --- a/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.cpp +++ b/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.cpp @@ -10,8 +10,7 @@ #include "gnb_cu_configuration_update_procedure.h" #include "srsran/asn1/f1ap/common.h" -#include "srsran/f1ap/common/f1ap_common.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srsran::srs_du; diff --git a/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.h b/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.h index 41ffcc5ca3..85433c5334 100644 --- a/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.h +++ b/lib/f1ap/du/procedures/gnb_cu_configuration_update_procedure.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/support/async/async_task.h" namespace srsran { diff --git a/lib/f1ap/du/procedures/proc_logger.h b/lib/f1ap/du/procedures/proc_logger.h index 907f72483f..89ff8c5895 100644 --- a/lib/f1ap/du/procedures/proc_logger.h +++ b/lib/f1ap/du/procedures/proc_logger.h @@ -10,7 +10,7 @@ #pragma once -#include "../../common/proc_logger.h" +#include "../../proc_logger.h" #include "../ue_context/f1ap_ue_context.h" namespace srsran { diff --git a/lib/f1ap/du/ue_context/f1ap_du_ue.h b/lib/f1ap/du/ue_context/f1ap_du_ue.h index df33e605d7..bfb9a35716 100644 --- a/lib/f1ap/du/ue_context/f1ap_du_ue.h +++ b/lib/f1ap/du/ue_context/f1ap_du_ue.h @@ -14,8 +14,8 @@ #include "ue_bearer_manager.h" #include "srsran/adt/slotted_array.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/du/f1ap_du.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/du_types.h" namespace srsran { diff --git a/lib/f1ap/du/ue_context/f1ap_ue_context.h b/lib/f1ap/du/ue_context/f1ap_ue_context.h index 030d39993a..b0531766cb 100644 --- a/lib/f1ap/du/ue_context/f1ap_ue_context.h +++ b/lib/f1ap/du/ue_context/f1ap_ue_context.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/du_types.h" #include "srsran/ran/rnti.h" #include "fmt/format.h" @@ -64,4 +64,4 @@ struct formatter { } }; -} // namespace fmt \ No newline at end of file +} // namespace fmt diff --git a/lib/f1ap/du/ue_context/f1c_du_bearer_impl.cpp b/lib/f1ap/du/ue_context/f1c_du_bearer_impl.cpp index 7017a8482d..14fc4ad528 100644 --- a/lib/f1ap/du/ue_context/f1c_du_bearer_impl.cpp +++ b/lib/f1ap/du/ue_context/f1c_du_bearer_impl.cpp @@ -12,7 +12,7 @@ #include "du/procedures/f1ap_du_event_manager.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/pdcp/pdcp_sn_util.h" #include "srsran/support/async/async_no_op_task.h" #include "srsran/support/async/async_timer.h" diff --git a/lib/f1ap/du/ue_context/f1c_du_bearer_impl.h b/lib/f1ap/du/ue_context/f1c_du_bearer_impl.h index cab05642e3..1358fbb9af 100644 --- a/lib/f1ap/du/ue_context/f1c_du_bearer_impl.h +++ b/lib/f1ap/du/ue_context/f1c_du_bearer_impl.h @@ -11,9 +11,10 @@ #pragma once #include "f1ap_ue_context.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/f1ap/du/f1c_bearer.h" +#include "srsran/f1ap/f1ap_message_notifier.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/rnti.h" #include "srsran/support/async/protocol_transaction_manager.h" #include "srsran/support/memory_pool/unsync_fixed_size_memory_block_pool.h" diff --git a/lib/f1ap/du/ue_context/ue_bearer_manager.h b/lib/f1ap/du/ue_context/ue_bearer_manager.h index 44be918d08..661b69e6d1 100644 --- a/lib/f1ap/du/ue_context/ue_bearer_manager.h +++ b/lib/f1ap/du/ue_context/ue_bearer_manager.h @@ -12,9 +12,9 @@ #include "f1ap_ue_context.h" #include "srsran/adt/slotted_array.h" -#include "srsran/f1ap/common/f1ap_common.h" #include "srsran/f1ap/du/f1c_bearer.h" #include "srsran/f1ap/du/f1c_rx_sdu_notifier.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/f1u/du/f1u_bearer.h" #include "srsran/f1u/du/f1u_rx_sdu_notifier.h" #include "srsran/f1u/du/f1u_tx_pdu_notifier.h" diff --git a/lib/f1ap/common/f1ap_asn1_packer.cpp b/lib/f1ap/f1ap_asn1_packer.cpp similarity index 96% rename from lib/f1ap/common/f1ap_asn1_packer.cpp rename to lib/f1ap/f1ap_asn1_packer.cpp index 8882342aad..b809ac0fa4 100644 --- a/lib/f1ap/common/f1ap_asn1_packer.cpp +++ b/lib/f1ap/f1ap_asn1_packer.cpp @@ -9,7 +9,7 @@ */ #include "f1ap_asn1_packer.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" namespace srsran { diff --git a/lib/f1ap/common/f1ap_asn1_packer.h b/lib/f1ap/f1ap_asn1_packer.h similarity index 100% rename from lib/f1ap/common/f1ap_asn1_packer.h rename to lib/f1ap/f1ap_asn1_packer.h diff --git a/lib/f1ap/common/f1ap_asn1_utils.h b/lib/f1ap/f1ap_asn1_utils.h similarity index 99% rename from lib/f1ap/common/f1ap_asn1_utils.h rename to lib/f1ap/f1ap_asn1_utils.h index 89c829d1a4..0e5076cf6c 100644 --- a/lib/f1ap/common/f1ap_asn1_utils.h +++ b/lib/f1ap/f1ap_asn1_utils.h @@ -13,7 +13,7 @@ #include "srsran/adt/expected.h" #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/paging_information.h" #include "srsran/support/error_handling.h" diff --git a/lib/f1ap/common/f1ap_common_messages.cpp b/lib/f1ap/f1ap_common_messages.cpp similarity index 100% rename from lib/f1ap/common/f1ap_common_messages.cpp rename to lib/f1ap/f1ap_common_messages.cpp diff --git a/lib/f1ap/common/f1ap_common_messages.h b/lib/f1ap/f1ap_common_messages.h similarity index 89% rename from lib/f1ap/common/f1ap_common_messages.h rename to lib/f1ap/f1ap_common_messages.h index b8f2dde34e..cee78952cb 100644 --- a/lib/f1ap/common/f1ap_common_messages.h +++ b/lib/f1ap/f1ap_common_messages.h @@ -12,8 +12,8 @@ #include "srsran/adt/optional.h" #include "srsran/asn1/f1ap/f1ap_ies.h" -#include "srsran/f1ap/common/f1ap_message.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_message.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" namespace srsran { diff --git a/lib/f1ap/gateways/f1c_local_connector_factory.cpp b/lib/f1ap/gateways/f1c_local_connector_factory.cpp index b8b4785597..7571b5dadb 100644 --- a/lib/f1ap/gateways/f1c_local_connector_factory.cpp +++ b/lib/f1ap/gateways/f1c_local_connector_factory.cpp @@ -10,7 +10,7 @@ #include "srsran/f1ap/gateways/f1c_local_connector_factory.h" #include "srsran/asn1/f1ap/f1ap.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/f1ap/gateways/f1c_network_client_factory.h" #include "srsran/f1ap/gateways/f1c_network_server_factory.h" #include "srsran/pcap/dlt_pcap.h" diff --git a/lib/f1ap/gateways/f1c_network_client_factory.cpp b/lib/f1ap/gateways/f1c_network_client_factory.cpp index 9958309a92..8be8dcdec5 100644 --- a/lib/f1ap/gateways/f1c_network_client_factory.cpp +++ b/lib/f1ap/gateways/f1c_network_client_factory.cpp @@ -10,7 +10,7 @@ #include "srsran/f1ap/gateways/f1c_network_client_factory.h" #include "srsran/asn1/f1ap/f1ap.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/gateways/sctp_network_client_factory.h" #include "srsran/pcap/dlt_pcap.h" #include "srsran/support/io/io_broker.h" diff --git a/lib/f1ap/gateways/f1c_network_server_factory.cpp b/lib/f1ap/gateways/f1c_network_server_factory.cpp index 00952c0722..85918de06a 100644 --- a/lib/f1ap/gateways/f1c_network_server_factory.cpp +++ b/lib/f1ap/gateways/f1c_network_server_factory.cpp @@ -10,7 +10,7 @@ #include "srsran/f1ap/gateways/f1c_network_server_factory.h" #include "srsran/asn1/f1ap/f1ap.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/gateways/sctp_network_server_factory.h" #include "srsran/pcap/dlt_pcap.h" #include "srsran/support/error_handling.h" diff --git a/lib/f1ap/common/log_helpers.cpp b/lib/f1ap/log_helpers.cpp similarity index 100% rename from lib/f1ap/common/log_helpers.cpp rename to lib/f1ap/log_helpers.cpp diff --git a/lib/f1ap/common/log_helpers.h b/lib/f1ap/log_helpers.h similarity index 97% rename from lib/f1ap/common/log_helpers.h rename to lib/f1ap/log_helpers.h index 912f9b6932..34f7f49f42 100644 --- a/lib/f1ap/common/log_helpers.h +++ b/lib/f1ap/log_helpers.h @@ -12,7 +12,7 @@ #include "srsran/adt/optional.h" #include "srsran/cu_cp/cu_cp_types.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/du_types.h" #include "srsran/ran/gnb_du_id.h" #include "srsran/srslog/srslog.h" diff --git a/lib/f1ap/common/proc_logger.h b/lib/f1ap/proc_logger.h similarity index 97% rename from lib/f1ap/common/proc_logger.h rename to lib/f1ap/proc_logger.h index 192b2b9cc2..b286b74984 100644 --- a/lib/f1ap/common/proc_logger.h +++ b/lib/f1ap/proc_logger.h @@ -10,7 +10,7 @@ #pragma once -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/support/format_utils.h" namespace srsran { diff --git a/tests/integrationtests/du_high/du_high_many_cells_test.cpp b/tests/integrationtests/du_high/du_high_many_cells_test.cpp index 3bdca384f1..b0b6dded05 100644 --- a/tests/integrationtests/du_high/du_high_many_cells_test.cpp +++ b/tests/integrationtests/du_high/du_high_many_cells_test.cpp @@ -14,7 +14,7 @@ #include "tests/test_doubles/scheduler/scheduler_result_test.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include using namespace srsran; diff --git a/tests/integrationtests/du_high/paging_test.cpp b/tests/integrationtests/du_high/paging_test.cpp index 4b390036c2..90a9414f85 100644 --- a/tests/integrationtests/du_high/paging_test.cpp +++ b/tests/integrationtests/du_high/paging_test.cpp @@ -11,12 +11,12 @@ /// \file /// \brief Tests that check the transmission of Paging messages by the DU-high class. -#include "lib/f1ap/common/f1ap_asn1_packer.h" +#include "lib/f1ap/f1ap_asn1_packer.h" #include "tests/integrationtests/du_high/test_utils/du_high_env_simulator.h" #include "tests/unittests/gateways/test_helpers.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/bcd_helper.h" #include "srsran/support/test_utils.h" diff --git a/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h b/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h index 4d80bc4dad..64042e38aa 100644 --- a/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h +++ b/tests/integrationtests/du_high/test_utils/du_high_env_simulator.h @@ -16,7 +16,7 @@ #include "tests/test_doubles/mac/mac_test_messages.h" #include "srsran/du/du_high/du_high.h" #include "srsran/du/du_high/du_high_configuration.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/scheduler/config/cell_config_builder_params.h" namespace srsran { diff --git a/tests/test_doubles/f1ap/f1ap_test_message_validators.cpp b/tests/test_doubles/f1ap/f1ap_test_message_validators.cpp index 28d01a4ae6..bed3c8a5b9 100644 --- a/tests/test_doubles/f1ap/f1ap_test_message_validators.cpp +++ b/tests/test_doubles/f1ap/f1ap_test_message_validators.cpp @@ -9,11 +9,11 @@ */ #include "f1ap_test_message_validators.h" -#include "../lib/f1ap/common/asn1_helpers.h" +#include "../../../lib/f1ap/asn1_helpers.h" #include "../tests/test_doubles/rrc/rrc_test_message_validators.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace asn1::f1ap; diff --git a/tests/test_doubles/f1ap/f1ap_test_message_validators.h b/tests/test_doubles/f1ap/f1ap_test_message_validators.h index 996e00cb57..2bf5b6bb1d 100644 --- a/tests/test_doubles/f1ap/f1ap_test_message_validators.h +++ b/tests/test_doubles/f1ap/f1ap_test_message_validators.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/adt/optional.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/lcid.h" #include "srsran/ran/nr_cgi.h" #include "srsran/ran/rnti.h" diff --git a/tests/test_doubles/f1ap/f1ap_test_messages.cpp b/tests/test_doubles/f1ap/f1ap_test_messages.cpp index 099fea4d7f..a2ca35f9ea 100644 --- a/tests/test_doubles/f1ap/f1ap_test_messages.cpp +++ b/tests/test_doubles/f1ap/f1ap_test_messages.cpp @@ -14,7 +14,7 @@ #include "srsran/asn1/f1ap/f1ap_ies.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/up_transport_layer_info.h" #include "srsran/support/test_utils.h" diff --git a/tests/test_doubles/f1ap/f1ap_test_messages.h b/tests/test_doubles/f1ap/f1ap_test_messages.h index f5ca25a438..f846ce6ead 100644 --- a/tests/test_doubles/f1ap/f1ap_test_messages.h +++ b/tests/test_doubles/f1ap/f1ap_test_messages.h @@ -16,7 +16,7 @@ #include "srsran/adt/byte_buffer.h" #include "srsran/adt/optional.h" #include "srsran/asn1/f1ap/f1ap_ies.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/gnb_du_id.h" #include "srsran/ran/lcid.h" #include "srsran/ran/nr_cell_identity.h" diff --git a/tests/test_doubles/f1ap/f1c_test_local_gateway.h b/tests/test_doubles/f1ap/f1c_test_local_gateway.h index 64864d7d99..0caa1c6ec8 100644 --- a/tests/test_doubles/f1ap/f1c_test_local_gateway.h +++ b/tests/test_doubles/f1ap/f1c_test_local_gateway.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/cu_cp/cu_cp_f1c_handler.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/f1ap/gateways/f1c_connection_client.h" #include "srsran/f1u/du/f1u_gateway.h" diff --git a/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp b/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp index 1427b4ee40..835cdb4252 100644 --- a/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_connectivity_test.cpp @@ -19,7 +19,7 @@ #include "srsran/asn1/rrc_nr/ul_dcch_msg.h" #include "srsran/asn1/rrc_nr/ul_dcch_msg_ies.h" #include "srsran/e1ap/common/e1ap_message.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include diff --git a/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp index 02189f503d..e2defc4a62 100644 --- a/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_initial_context_setup_test.cpp @@ -19,7 +19,7 @@ #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/asn1/ngap/ngap_pdu_contents.h" #include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include diff --git a/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp b/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp index c02184c468..68ab637f0e 100644 --- a/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_inter_du_handover_test.cpp @@ -15,8 +15,8 @@ #include "tests/unittests/e1ap/common/e1ap_cu_cp_test_messages.h" #include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h" #include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_message.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ngap/ngap_message.h" #include "srsran/support/test_utils.h" #include diff --git a/tests/unittests/cu_cp/cu_cp_paging_test.cpp b/tests/unittests/cu_cp/cu_cp_paging_test.cpp index 06cda40590..f85d307157 100644 --- a/tests/unittests/cu_cp/cu_cp_paging_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_paging_test.cpp @@ -15,7 +15,7 @@ #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" #include "srsran/asn1/ngap/ngap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp index b491b40202..7d7069aa08 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp @@ -20,7 +20,7 @@ #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/asn1/ngap/ngap_pdu_contents.h" #include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include "srsran/ran/cu_types.h" #include "srsran/ran/lcid.h" diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp index d02cdfe9a1..48f242e908 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_release_test.cpp @@ -19,7 +19,7 @@ #include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h" #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include "srsran/ran/cu_types.h" #include diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp index a8b0d7e510..ed5d4c96f7 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_setup_test.cpp @@ -18,7 +18,7 @@ #include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h" #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include "srsran/ran/cu_types.h" #include "srsran/ran/lcid.h" diff --git a/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp b/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp index d2cf3cbf96..a6edac3d06 100644 --- a/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_reestablishment_test.cpp @@ -17,7 +17,7 @@ #include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" #include "srsran/asn1/ngap/ngap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include diff --git a/tests/unittests/cu_cp/cu_cp_setup_test.cpp b/tests/unittests/cu_cp/cu_cp_setup_test.cpp index be0fc0b74a..d55e4a75fb 100644 --- a/tests/unittests/cu_cp/cu_cp_setup_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_setup_test.cpp @@ -16,7 +16,7 @@ #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" #include "srsran/asn1/rrc_nr/dl_ccch_msg.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.cpp b/tests/unittests/cu_cp/cu_cp_test_environment.cpp index d5d999a6f8..9beb77478f 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.cpp +++ b/tests/unittests/cu_cp/cu_cp_test_environment.cpp @@ -28,7 +28,7 @@ #include "srsran/cu_cp/cu_cp_types.h" #include "srsran/e1ap/common/e1ap_message.h" #include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ngap/ngap_message.h" #include "srsran/ran/cu_types.h" #include "srsran/ran/plmn_identity.h" diff --git a/tests/unittests/cu_cp/cu_cp_test_messages.cpp b/tests/unittests/cu_cp/cu_cp_test_messages.cpp index 9da4642014..7397fda4fe 100644 --- a/tests/unittests/cu_cp/cu_cp_test_messages.cpp +++ b/tests/unittests/cu_cp/cu_cp_test_messages.cpp @@ -14,7 +14,7 @@ #include "tests/unittests/e1ap/common/e1ap_cu_cp_test_messages.h" #include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h" #include "srsran/e1ap/common/e1ap_message.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srs_cu_cp; diff --git a/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp b/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp index 02123d5682..215ae5eb21 100644 --- a/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_ue_context_release_test.cpp @@ -18,8 +18,8 @@ #include "tests/unittests/ngap/ngap_test_messages.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents_ue.h" #include "srsran/e1ap/common/e1ap_types.h" -#include "srsran/f1ap/common/f1ap_message.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_message.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ngap/ngap_message.h" #include diff --git a/tests/unittests/cu_cp/du_processor_test_messages.cpp b/tests/unittests/cu_cp/du_processor_test_messages.cpp index 9bbc8e23b0..fadb17e2ee 100644 --- a/tests/unittests/cu_cp/du_processor_test_messages.cpp +++ b/tests/unittests/cu_cp/du_processor_test_messages.cpp @@ -9,11 +9,11 @@ */ #include "du_processor_test_messages.h" -#include "lib/f1ap/common/asn1_helpers.h" +#include "lib/f1ap/asn1_helpers.h" #include "lib/f1ap/cu_cp/f1ap_asn1_helpers.h" #include "lib/f1ap/cu_cp/procedures/f1_setup_procedure.h" #include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srs_cu_cp; diff --git a/tests/unittests/cu_cp/du_processor_test_messages.h b/tests/unittests/cu_cp/du_processor_test_messages.h index f29306cfad..51c41e8bf1 100644 --- a/tests/unittests/cu_cp/du_processor_test_messages.h +++ b/tests/unittests/cu_cp/du_processor_test_messages.h @@ -11,9 +11,9 @@ #pragma once #include "srsran/cu_cp/cu_cp_types.h" -#include "srsran/f1ap/common/f1ap_message.h" #include "srsran/f1ap/cu_cp/du_setup_notifier.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" +#include "srsran/f1ap/f1ap_message.h" namespace srsran { namespace srs_cu_cp { diff --git a/tests/unittests/cu_cp/test_doubles/dummy_du.cpp b/tests/unittests/cu_cp/test_doubles/dummy_du.cpp index d8c95e7acb..c65d749f2f 100644 --- a/tests/unittests/cu_cp/test_doubles/dummy_du.cpp +++ b/tests/unittests/cu_cp/test_doubles/dummy_du.cpp @@ -11,7 +11,7 @@ #include "dummy_du.h" #include "srsran/adt/concurrent_queue.h" #include "srsran/cu_cp/cu_cp_f1c_handler.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/support/error_handling.h" using namespace srsran; diff --git a/tests/unittests/cu_cp/test_doubles/mock_du.cpp b/tests/unittests/cu_cp/test_doubles/mock_du.cpp index 70d9e1c5e1..c02ba7c777 100644 --- a/tests/unittests/cu_cp/test_doubles/mock_du.cpp +++ b/tests/unittests/cu_cp/test_doubles/mock_du.cpp @@ -9,12 +9,12 @@ */ #include "mock_du.h" -#include "lib/f1ap/common/f1ap_asn1_utils.h" +#include "lib/f1ap/f1ap_asn1_utils.h" #include "tests/test_doubles/f1ap/f1ap_test_messages.h" #include "srsran/adt/mutexed_mpmc_queue.h" #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/cu_cp/cu_cp_f1c_handler.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/support/error_handling.h" #include #include diff --git a/tests/unittests/cu_cp/test_doubles/mock_du.h b/tests/unittests/cu_cp/test_doubles/mock_du.h index 25bdcaabcb..af41e6d03d 100644 --- a/tests/unittests/cu_cp/test_doubles/mock_du.h +++ b/tests/unittests/cu_cp/test_doubles/mock_du.h @@ -11,7 +11,7 @@ #pragma once #include "srsran/adt/byte_buffer.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/ran/lcid.h" #include @@ -54,4 +54,4 @@ struct mock_du_params { std::unique_ptr create_mock_du(mock_du_params params); } // namespace srs_cu_cp -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/tests/unittests/f1ap/common/f1ap_asn1_helpers_test.cpp b/tests/unittests/f1ap/common/f1ap_asn1_helpers_test.cpp index b55ebfcf75..824f000d5b 100644 --- a/tests/unittests/f1ap/common/f1ap_asn1_helpers_test.cpp +++ b/tests/unittests/f1ap/common/f1ap_asn1_helpers_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/f1ap/common/asn1_helpers.h" +#include "lib/f1ap/asn1_helpers.h" #include "srsran/asn1/f1ap/f1ap.h" #include "srsran/ran/nr_cgi.h" #include "srsran/ran/up_transport_layer_info.h" diff --git a/tests/unittests/f1ap/common/f1ap_asn1_packer_test.cpp b/tests/unittests/f1ap/common/f1ap_asn1_packer_test.cpp index bb16a44da2..b6fd61053d 100644 --- a/tests/unittests/f1ap/common/f1ap_asn1_packer_test.cpp +++ b/tests/unittests/f1ap/common/f1ap_asn1_packer_test.cpp @@ -8,7 +8,7 @@ * */ -#include "lib/f1ap/common/f1ap_asn1_packer.h" +#include "lib/f1ap/f1ap_asn1_packer.h" #include "test_helpers.h" #include "tests/unittests/f1ap/cu_cp/f1ap_cu_test_helpers.h" #include "tests/unittests/gateways/test_helpers.h" diff --git a/tests/unittests/f1ap/common/f1ap_cu_test_messages.cpp b/tests/unittests/f1ap/common/f1ap_cu_test_messages.cpp index 49b982a271..6a8269bb2d 100644 --- a/tests/unittests/f1ap/common/f1ap_cu_test_messages.cpp +++ b/tests/unittests/f1ap/common/f1ap_cu_test_messages.cpp @@ -11,8 +11,8 @@ #include "f1ap_cu_test_messages.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" #include "srsran/f1ap/cu_cp/f1ap_cu_ue_context_update.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace srs_cu_cp; diff --git a/tests/unittests/f1ap/common/f1ap_cu_test_messages.h b/tests/unittests/f1ap/common/f1ap_cu_test_messages.h index 0a5c2742f6..f8dc9f3f79 100644 --- a/tests/unittests/f1ap/common/f1ap_cu_test_messages.h +++ b/tests/unittests/f1ap/common/f1ap_cu_test_messages.h @@ -12,8 +12,8 @@ #include "../../../test_doubles/f1ap/f1ap_test_messages.h" #include "srsran/asn1/f1ap/f1ap_ies.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include namespace srsran { diff --git a/tests/unittests/f1ap/common/f1ap_du_test_messages.cpp b/tests/unittests/f1ap/common/f1ap_du_test_messages.cpp index 95a7c2f9b7..b1c895c16d 100644 --- a/tests/unittests/f1ap/common/f1ap_du_test_messages.cpp +++ b/tests/unittests/f1ap/common/f1ap_du_test_messages.cpp @@ -11,7 +11,7 @@ #include "f1ap_du_test_messages.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" using namespace srsran; using namespace asn1::f1ap; diff --git a/tests/unittests/f1ap/common/f1ap_du_test_messages.h b/tests/unittests/f1ap/common/f1ap_du_test_messages.h index 065fdcf5b1..93eaa2c4e2 100644 --- a/tests/unittests/f1ap/common/f1ap_du_test_messages.h +++ b/tests/unittests/f1ap/common/f1ap_du_test_messages.h @@ -12,7 +12,7 @@ #include "srsran/adt/byte_buffer.h" #include "srsran/asn1/f1ap/f1ap_ies.h" -#include "srsran/f1ap/common/f1ap_common.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/ran/lcid.h" namespace srsran { @@ -30,4 +30,4 @@ generate_f1_setup_failure_message(unsigned transaction_id, /// \brief Generate dummy F1AP DL RRC Message Transfer message (CU -> DU). f1ap_message generate_f1ap_dl_rrc_message_transfer(srb_id_t srb_id, const byte_buffer& rrc_container); -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/tests/unittests/f1ap/common/test_helpers.h b/tests/unittests/f1ap/common/test_helpers.h index 3f50c557a8..8434d0ee08 100644 --- a/tests/unittests/f1ap/common/test_helpers.h +++ b/tests/unittests/f1ap/common/test_helpers.h @@ -10,8 +10,9 @@ #pragma once -#include "srsran/f1ap/common/f1ap_common.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" +#include "srsran/f1ap/f1ap_message_handler.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/gateways/network_gateway.h" #include "srsran/support/error_handling.h" diff --git a/tests/unittests/f1ap/cu_cp/f1ap_cu_test.cpp b/tests/unittests/f1ap/cu_cp/f1ap_cu_test.cpp index c276d06191..1082042d65 100644 --- a/tests/unittests/f1ap/cu_cp/f1ap_cu_test.cpp +++ b/tests/unittests/f1ap/cu_cp/f1ap_cu_test.cpp @@ -9,7 +9,7 @@ */ #include "f1ap_cu_test_helpers.h" -#include "lib/f1ap/common/asn1_helpers.h" +#include "lib/f1ap/asn1_helpers.h" #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" diff --git a/tests/unittests/f1ap/cu_cp/f1ap_cu_test_helpers.h b/tests/unittests/f1ap/cu_cp/f1ap_cu_test_helpers.h index f49eac335e..b511577619 100644 --- a/tests/unittests/f1ap/cu_cp/f1ap_cu_test_helpers.h +++ b/tests/unittests/f1ap/cu_cp/f1ap_cu_test_helpers.h @@ -14,9 +14,9 @@ #include "../common/test_helpers.h" #include "tests/test_doubles/f1ap/f1c_test_local_gateway.h" #include "srsran/cu_cp/cu_cp_types.h" -#include "srsran/f1ap/common/f1ap_common.h" #include "srsran/f1ap/cu_cp/f1ap_configuration.h" #include "srsran/f1ap/cu_cp/f1ap_cu.h" +#include "srsran/f1ap/f1ap_message_notifier.h" #include "srsran/support/async/fifo_async_task_scheduler.h" #include "srsran/support/executors/manual_task_worker.h" #include diff --git a/tests/unittests/f1ap/cu_cp/f1ap_cu_ue_context_test.cpp b/tests/unittests/f1ap/cu_cp/f1ap_cu_ue_context_test.cpp index 37be0cabb3..d8cd4a563c 100644 --- a/tests/unittests/f1ap/cu_cp/f1ap_cu_ue_context_test.cpp +++ b/tests/unittests/f1ap/cu_cp/f1ap_cu_ue_context_test.cpp @@ -10,7 +10,7 @@ #include "f1ap_cu_test_helpers.h" #include "lib/f1ap/cu_cp/ue_context/f1ap_cu_ue_context.h" -#include "srsran/f1ap/common/f1ap_ue_id.h" +#include "srsran/f1ap/f1ap_ue_id_types.h" #include "srsran/support/executors/manual_task_worker.h" #include "srsran/support/test_utils.h" diff --git a/tests/unittests/f1ap/du/f1ap_du_setup_procedure_test.cpp b/tests/unittests/f1ap/du/f1ap_du_setup_procedure_test.cpp index 7abc0f549f..6aa1ed1cc4 100644 --- a/tests/unittests/f1ap/du/f1ap_du_setup_procedure_test.cpp +++ b/tests/unittests/f1ap/du/f1ap_du_setup_procedure_test.cpp @@ -9,7 +9,7 @@ */ #include "f1ap_du_test_helpers.h" -#include "lib/f1ap/common/f1ap_asn1_utils.h" +#include "lib/f1ap/f1ap_asn1_utils.h" #include "unittests/f1ap/common/f1ap_du_test_messages.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" #include "srsran/support/async/async_test_utils.h" diff --git a/tests/unittests/f1ap/du/f1ap_du_test_helpers.cpp b/tests/unittests/f1ap/du/f1ap_du_test_helpers.cpp index 03c8588be8..31d2b7223f 100644 --- a/tests/unittests/f1ap/du/f1ap_du_test_helpers.cpp +++ b/tests/unittests/f1ap/du/f1ap_du_test_helpers.cpp @@ -9,7 +9,7 @@ */ #include "f1ap_du_test_helpers.h" -#include "lib/f1ap/common/f1ap_asn1_utils.h" +#include "lib/f1ap/f1ap_asn1_utils.h" #include "test_doubles/f1ap/f1ap_test_messages.h" #include "unittests/f1ap/common/f1ap_du_test_messages.h" #include "srsran/asn1/f1ap/common.h" diff --git a/tests/unittests/f1ap/du/f1ap_du_test_helpers.h b/tests/unittests/f1ap/du/f1ap_du_test_helpers.h index 8000ad4f09..224c7b10f9 100644 --- a/tests/unittests/f1ap/du/f1ap_du_test_helpers.h +++ b/tests/unittests/f1ap/du/f1ap_du_test_helpers.h @@ -13,10 +13,9 @@ #include "lib/du/du_high/du_manager/converters/f1ap_configuration_helpers.h" #include "srsran/adt/slotted_array.h" #include "srsran/asn1/f1ap/f1ap_ies.h" -#include "srsran/f1ap/common/f1ap_common.h" -#include "srsran/f1ap/common/f1ap_message.h" #include "srsran/f1ap/du/f1ap_du.h" #include "srsran/f1ap/du/f1ap_du_factory.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/f1ap/gateways/f1c_connection_client.h" #include "srsran/f1u/du/f1u_rx_sdu_notifier.h" #include "srsran/support/async/async_no_op_task.h" diff --git a/tests/unittests/f1ap/gateways/f1c_gateway_test.cpp b/tests/unittests/f1ap/gateways/f1c_gateway_test.cpp index 8b3a9ba857..3839fb27ca 100644 --- a/tests/unittests/f1ap/gateways/f1c_gateway_test.cpp +++ b/tests/unittests/f1ap/gateways/f1c_gateway_test.cpp @@ -12,7 +12,7 @@ #include "srsran/asn1/f1ap/common.h" #include "srsran/asn1/f1ap/f1ap_pdu_contents.h" #include "srsran/cu_cp/cu_cp_f1c_handler.h" -#include "srsran/f1ap/common/f1ap_message.h" +#include "srsran/f1ap/f1ap_message.h" #include "srsran/f1ap/gateways/f1c_local_connector_factory.h" #include "srsran/pcap/dlt_pcap.h" #include "srsran/support/io/io_broker_factory.h" @@ -278,4 +278,4 @@ TEST_P(f1c_gateway_link_test, when_du_tx_pdu_notifier_is_closed_then_connection_ link->cu_gw_assoc_close_signaled.wait(); } -INSTANTIATE_TEST_SUITE_P(f1c_gateway_link_tests, f1c_gateway_link_test, ::testing::Values(true, false)); \ No newline at end of file +INSTANTIATE_TEST_SUITE_P(f1c_gateway_link_tests, f1c_gateway_link_test, ::testing::Values(true, false)); From af4c28cacd269cf51baa82f356faa99308936515 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 20 Sep 2024 18:49:58 +0200 Subject: [PATCH 097/174] sched: fix traversal of pending HARQ reTxs --- lib/scheduler/policy/scheduler_time_rr.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/scheduler/policy/scheduler_time_rr.cpp b/lib/scheduler/policy/scheduler_time_rr.cpp index 8d8f65bf8e..34a26d0a31 100644 --- a/lib/scheduler/policy/scheduler_time_rr.cpp +++ b/lib/scheduler/policy/scheduler_time_rr.cpp @@ -221,7 +221,10 @@ static alloc_result alloc_dl_retxs(const slice_ue_repository& ue_db, ran_slice_id_t slice_id, dl_harq_pending_retx_list harq_list) { - for (auto h : harq_list) { + for (auto it = harq_list.begin(); it != harq_list.end();) { + // Note: During retx alloc, the pending HARQ list will mutate. So, we prefetch the next node. + auto prev_it = it++; + auto h = *prev_it; if (h.get_grant_params().slice_id != slice_id or not ue_db.contains(h.ue_index())) { continue; } @@ -298,7 +301,10 @@ static alloc_result alloc_ul_retxs(const slice_ue_repository& ue_db, ran_slice_id_t slice_id, ul_harq_pending_retx_list harq_list) { - for (auto h : harq_list) { + for (auto it = harq_list.begin(); it != harq_list.end();) { + // Note: During retx alloc, the pending HARQ list will mutate. So, we prefetch the next node. + auto prev_it = it++; + auto h = *prev_it; if (h.get_grant_params().slice_id != slice_id or not ue_db.contains(h.ue_index())) { continue; } From c32efc5d2ad3ec09a6b6185472c50df9dfa719ab Mon Sep 17 00:00:00 2001 From: asaezper Date: Fri, 20 Sep 2024 12:22:27 +0200 Subject: [PATCH 098/174] ci: slow uesim handover --- .gitlab-ci.yml | 3 +++ .gitlab/ci/e2e/.env | 2 +- tests/e2e/tests/attach_detach.py | 6 +++--- tests/e2e/tests/handover.py | 17 +++++++++++------ tests/e2e/tests/iperf.py | 18 +++++++++--------- tests/e2e/tests/iperf_alt.py | 2 +- tests/e2e/tests/ping.py | 14 +++++++------- tests/e2e/tests/reestablishment.py | 14 +++++++------- tests/e2e/tests/steps/configuration.py | 2 +- tests/e2e/tests/steps/stub.py | 4 ++-- tests/e2e/tests/test_mode.py | 4 ++-- tests/e2e/tests/validate_configuration.py | 4 ++-- tests/e2e/tests/viavi.py | 9 ++++----- 13 files changed, 53 insertions(+), 46 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 61aec530d4..bfe8eff139 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -321,6 +321,9 @@ e2e tests tox: before_script: - apk add build-base extends: .tox + parallel: + matrix: + - PYTHON_VERSION: ["3.9", "3.10", "3.11", "3.12"] ################################################################################ ## Build + Unit Tests + Integration tests diff --git a/.gitlab/ci/e2e/.env b/.gitlab/ci/e2e/.env index a8879bac86..aefba9a81d 100644 --- a/.gitlab/ci/e2e/.env +++ b/.gitlab/ci/e2e/.env @@ -1,6 +1,6 @@ SRSGNB_REGISTRY_URI=registry.gitlab.com/softwareradiosystems/srsgnb RETINA_REGISTRY_PREFIX=registry.gitlab.com/softwareradiosystems/ci/retina -RETINA_VERSION=0.52.23 +RETINA_VERSION=0.52.24 UBUNTU_VERSION=24.04 AMARISOFT_VERSION=2023-09-08 SRSUE_VERSION=23.11 diff --git a/tests/e2e/tests/attach_detach.py b/tests/e2e/tests/attach_detach.py index 6b1aad8d3b..9384d0832d 100644 --- a/tests/e2e/tests/attach_detach.py +++ b/tests/e2e/tests/attach_detach.py @@ -84,7 +84,7 @@ def test_smoke( ) @mark.zmq @mark.flaky(reruns=3, only_rerun=["failed to start", "IPerf Data Invalid"]) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -137,7 +137,7 @@ def test_zmq( ), ) @mark.rf -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_rf_udp( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -175,7 +175,7 @@ def test_rf_udp( ) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def _attach_and_detach_multi_ues( retina_manager: RetinaTestManager, retina_data: RetinaTestData, diff --git a/tests/e2e/tests/handover.py b/tests/e2e/tests/handover.py index ec9c00654d..6faf1f377b 100644 --- a/tests/e2e/tests/handover.py +++ b/tests/e2e/tests/handover.py @@ -62,6 +62,7 @@ def test_smoke_sequentially( common_scs=30, bandwidth=50, noise_spd=0, + sleep_between_movement_steps=2, always_download_artifacts=False, ) @@ -77,7 +78,7 @@ def test_smoke_sequentially( ) @mark.zmq @mark.flaky(reruns=2, only_rerun=["failed to start", "Attach timeout reached", "StatusCode.ABORTED"]) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq_handover_sequentially( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -104,10 +105,11 @@ def test_zmq_handover_sequentially( common_scs=common_scs, bandwidth=bandwidth, noise_spd=noise_spd, + sleep_between_movement_steps=10, ) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def _handover_sequentially( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -119,6 +121,7 @@ def _handover_sequentially( common_scs: int, bandwidth: int, noise_spd: int, + sleep_between_movement_steps, always_download_artifacts: bool = True, ): with _handover_multi_ues( @@ -136,6 +139,7 @@ def _handover_sequentially( time_alignment_calibration=0, always_download_artifacts=always_download_artifacts, noise_spd=noise_spd, + sleep_between_movement_steps=sleep_between_movement_steps, warning_as_errors=True, ) as (ue_attach_info_dict, movements, traffic_seconds): @@ -148,8 +152,8 @@ def _handover_sequentially( ping_task_array = ping_start(ue_attach_info_dict, fivegc, traffic_seconds) - for from_position, to_position, movement_steps, sleep_between_movement_steps in movements: - _do_ho((ue_stub,), from_position, to_position, movement_steps, sleep_between_movement_steps) + for _from_position, _to_position, _movement_steps, _sleep_between_movement_steps in movements: + _do_ho((ue_stub,), _from_position, _to_position, _movement_steps, _sleep_between_movement_steps) ping_wait_until_finish(ping_task_array) @@ -165,7 +169,7 @@ def _handover_sequentially( ) @mark.zmq @mark.flaky(reruns=2, only_rerun=["failed to start", "Attach timeout reached", "StatusCode.ABORTED"]) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def test_zmq_handover_parallel( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -196,6 +200,7 @@ def test_zmq_handover_parallel( time_alignment_calibration=0, always_download_artifacts=True, noise_spd=noise_spd, + sleep_between_movement_steps=10, warning_as_errors=True, ) as (ue_attach_info_dict, movements, traffic_seconds): @@ -211,7 +216,7 @@ def test_zmq_handover_parallel( ping_wait_until_finish(ping_task_array) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals @contextmanager def _handover_multi_ues( retina_manager: RetinaTestManager, diff --git a/tests/e2e/tests/iperf.py b/tests/e2e/tests/iperf.py index 15c5129513..728bf93633 100644 --- a/tests/e2e/tests/iperf.py +++ b/tests/e2e/tests/iperf.py @@ -166,7 +166,7 @@ def get_maximum_throughput(bandwidth: int, band: int, direction: IPerfDir, proto (param(3, 15, 10, id="band:%s-scs:%s-bandwidth:%s"),), ) @mark.zmq_srsue -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_srsue( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -232,7 +232,7 @@ def test_srsue( reruns=2, only_rerun=["failed to start", "Exception calling application", "Attach timeout reached", "Some packages got lost"], ) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_android( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -297,7 +297,7 @@ def test_android( reruns=2, only_rerun=["failed to start", "Exception calling application", "Attach timeout reached", "Some packages got lost"], ) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_android_hp( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -349,7 +349,7 @@ def test_android_hp( ) @mark.zmq_2x2_mimo @mark.flaky(reruns=2, only_rerun=["failed to start", "Attach timeout reached", "5GC crashed"]) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq_2x2_mimo( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -412,7 +412,7 @@ def test_zmq_2x2_mimo( ) @mark.zmq_4x4_mimo @mark.flaky(reruns=2, only_rerun=["failed to start", "Attach timeout reached", "5GC crashed"]) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq_4x4_mimo( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -469,7 +469,7 @@ def test_zmq_4x4_mimo( ) @mark.zmq @mark.smoke -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_smoke( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -549,7 +549,7 @@ def test_smoke( "5GC crashed", ], ) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -613,7 +613,7 @@ def test_zmq( ), ) @mark.rf -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_rf( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -651,7 +651,7 @@ def test_rf( ) -# pylint: disable=too-many-arguments, too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments, too-many-locals def _iperf( retina_manager: RetinaTestManager, retina_data: RetinaTestData, diff --git a/tests/e2e/tests/iperf_alt.py b/tests/e2e/tests/iperf_alt.py index f59adfed78..b10e24e794 100644 --- a/tests/e2e/tests/iperf_alt.py +++ b/tests/e2e/tests/iperf_alt.py @@ -39,7 +39,7 @@ (param("log --hex_max_size=32", id="hex_max_size"),), ) @mark.zmq_single_ue -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_multiple_configs_zmq( retina_manager: RetinaTestManager, retina_data: RetinaTestData, diff --git a/tests/e2e/tests/ping.py b/tests/e2e/tests/ping.py index 66727dcaa3..5794aaeb43 100644 --- a/tests/e2e/tests/ping.py +++ b/tests/e2e/tests/ping.py @@ -47,7 +47,7 @@ reruns=2, only_rerun=["failed to start", "Exception calling application", "Attach timeout reached", "Some packages got lost"], ) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_android( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -101,7 +101,7 @@ def test_android( reruns=2, only_rerun=["failed to start", "Exception calling application", "Attach timeout reached", "Some packages got lost"], ) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_android_hp( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -160,7 +160,7 @@ def test_android_hp( "5GC crashed", ], ) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -199,7 +199,7 @@ def test_zmq( (param(3, 15, 10, id="band:%s-scs:%s-bandwidth:%s"),), ) @mark.zmq_valgrind -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq_valgrind( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -255,7 +255,7 @@ def test_zmq_valgrind( ), ) @mark.rf -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_rf( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -292,7 +292,7 @@ def test_rf( (param(3, 15, 10, id="band:%s-scs:%s-bandwidth:%s"),), ) @mark.rf_not_crash -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_rf_does_not_crash( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -328,7 +328,7 @@ def test_rf_does_not_crash( stop(ue_4, gnb, fivegc, retina_data, log_search=False) -# pylint: disable=too-many-arguments, too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments, too-many-locals def _ping( retina_manager: RetinaTestManager, retina_data: RetinaTestData, diff --git a/tests/e2e/tests/reestablishment.py b/tests/e2e/tests/reestablishment.py index 6d0ace5c4e..ccee31109e 100644 --- a/tests/e2e/tests/reestablishment.py +++ b/tests/e2e/tests/reestablishment.py @@ -80,7 +80,7 @@ def test_smoke_sequentially( ) @mark.zmq @mark.flaky(reruns=2, only_rerun=_ONLY_RERUN) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_zmq_reestablishment_sequentially( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -110,7 +110,7 @@ def test_zmq_reestablishment_sequentially( ) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def _reestablishment_sequentially_ping( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -179,7 +179,7 @@ def _reestablishment_sequentially_ping( ) @mark.zmq @mark.flaky(reruns=2, only_rerun=_ONLY_RERUN) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def test_zmq_reestablishment_sequentially_full_rate( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -248,7 +248,7 @@ def test_zmq_reestablishment_sequentially_full_rate( ) @mark.zmq @mark.flaky(reruns=2, only_rerun=_ONLY_RERUN) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def test_zmq_reestablishment_parallel( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -314,7 +314,7 @@ def test_zmq_reestablishment_parallel( ) @mark.zmq @mark.flaky(reruns=2, only_rerun=_ONLY_RERUN) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def test_zmq_reestablishment_parallel_full_rate( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -375,7 +375,7 @@ def test_zmq_reestablishment_parallel_full_rate( ) -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def _iterator_over_attached_ues( retina_manager: RetinaTestManager, retina_data: RetinaTestData, @@ -431,7 +431,7 @@ def _iterator_over_attached_ues( yield {}, ue_attach_info_dict -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals @contextmanager def _test_reestablishments( retina_manager: RetinaTestManager, diff --git a/tests/e2e/tests/steps/configuration.py b/tests/e2e/tests/steps/configuration.py index 0b8ca7e0a3..3e40168a4d 100644 --- a/tests/e2e/tests/steps/configuration.py +++ b/tests/e2e/tests/steps/configuration.py @@ -20,7 +20,7 @@ from retina.launcher.public import MetricServerInfo -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments # pylint: disable=too-many-locals def configure_test_parameters( retina_manager: RetinaTestManager, diff --git a/tests/e2e/tests/steps/stub.py b/tests/e2e/tests/steps/stub.py index e46e45429c..2279906594 100644 --- a/tests/e2e/tests/steps/stub.py +++ b/tests/e2e/tests/steps/stub.py @@ -50,7 +50,7 @@ INTER_UE_START_PERIOD: int = 0 -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def start_and_attach( ue_array: Sequence[UEStub], gnb: GNBStub, @@ -98,7 +98,7 @@ def _get_hplmn(imsi: str) -> PLMN: return hplmn -# pylint: disable=too-many-arguments,too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals def start_network( ue_array: Sequence[UEStub], gnb: GNBStub, diff --git a/tests/e2e/tests/test_mode.py b/tests/e2e/tests/test_mode.py index 71089a5641..a552faea99 100644 --- a/tests/e2e/tests/test_mode.py +++ b/tests/e2e/tests/test_mode.py @@ -44,7 +44,7 @@ ), ) @mark.test_mode -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def test_ue( # Retina retina_manager: RetinaTestManager, @@ -177,7 +177,7 @@ def test_ru_not_crash( _test_ru(retina_manager, retina_data, gnb, gnb_stop_timeout=150, warning_as_errors=False, fail_if_kos=False) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def _test_ru( # Retina retina_manager: RetinaTestManager, diff --git a/tests/e2e/tests/validate_configuration.py b/tests/e2e/tests/validate_configuration.py index dd911a9939..ee8757fb9e 100644 --- a/tests/e2e/tests/validate_configuration.py +++ b/tests/e2e/tests/validate_configuration.py @@ -46,7 +46,7 @@ def test_rf_b200_config( gnb: GNBStub, config_file: str, timeout: int = RF_MAX_TIMEOUT, -): # pylint: disable=too-many-arguments +): # pylint: disable=too-many-arguments,too-many-positional-arguments """ Run gnb with B200 example config and validate it doesn't crash. """ @@ -68,7 +68,7 @@ def test_rf_n300_config( run_config(retina_manager, retina_data, fivegc, gnb, timeout, N300_CONFIG_FILE, extra_config) -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def run_config( retina_manager: RetinaTestManager, retina_data: RetinaTestData, diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index baf7e8ec87..727f71c35b 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -130,7 +130,7 @@ def viavi_manual_test_timeout(request): @mark.viavi_manual -# pylint: disable=too-many-arguments, too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments, too-many-locals def test_viavi_manual( capsys: pytest.CaptureFixture[str], # Retina @@ -193,7 +193,7 @@ def test_viavi_manual( reruns=2, only_rerun=_FLAKY_ERROR_LIST, ) -# pylint: disable=too-many-arguments, too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments, too-many-locals def test_viavi( capsys: pytest.CaptureFixture[str], # Retina @@ -249,7 +249,7 @@ def test_viavi( reruns=2, only_rerun=_FLAKY_ERROR_LIST, ) -# pylint: disable=too-many-arguments, too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments, too-many-locals def test_viavi_debug( capsys: pytest.CaptureFixture[str], # Retina @@ -293,7 +293,7 @@ def test_viavi_debug( ) -# pylint: disable=too-many-arguments, too-many-locals +# pylint: disable=too-many-arguments,too-many-positional-arguments, too-many-locals def _test_viavi( capsys: pytest.CaptureFixture[str], # Retina @@ -335,7 +335,6 @@ def _test_viavi( "enable_qos_viavi": test_declaration.enable_qos_viavi, "nof_antennas_dl": 4, "nof_antennas_ul": 1, - "rlc_metrics": True, }, }, } From 27a1c7f7b99942447ea7c700592532bdda239c5b Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 23 Sep 2024 10:11:14 +0200 Subject: [PATCH 099/174] ci,viavi: increase assert level --- .gitlab/ci/build.yml | 6 ++++-- .gitlab/ci/e2e.yml | 9 ++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index 43dfafdc03..551fac19a0 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -1865,7 +1865,7 @@ basic avx512 dpdk: DPDK_VERSION: "23.11.1_avx512" MARCH: x86-64-v4 FORCE_DEBUG_INFO: "True" - ASSERT_LEVEL: MINIMAL + ASSERT_LEVEL: AUTO tags: ["${AMD64_AVX512_TAG}"] after_script: - *build_after_script @@ -1875,8 +1875,10 @@ basic avx512 dpdk: basic avx512 dpdk withassert: extends: basic avx512 dpdk + rules: + - if: $CI_DESCRIPTION =~ /Nightly E2E Tests/ variables: - ASSERT_LEVEL: NORMAL + ASSERT_LEVEL: PARANOID ####### # Web # diff --git a/.gitlab/ci/e2e.yml b/.gitlab/ci/e2e.yml index 4ffe3ccda4..cbdcd1f14c 100644 --- a/.gitlab/ci/e2e.yml +++ b/.gitlab/ci/e2e.yml @@ -618,20 +618,19 @@ viavi-extended: extends: .viavi rules: - if: $CI_DESCRIPTION =~ /Weekly/ + variables: + KEYWORDS: "extended" + allow_failure: true needs: - job: "basic avx512 dpdk" artifacts: true - *retina-needs - parallel: - matrix: - - KEYWORDS: [ - "extended", - ] viavi-debug: extends: .viavi variables: MARKERS: "viavi_debug" + allow_failure: true needs: - job: "basic avx512 dpdk withassert" artifacts: true From 1ed36d53ff4ed5fb673250ef9e55a01555314812 Mon Sep 17 00:00:00 2001 From: asaezper Date: Mon, 23 Sep 2024 10:11:32 +0200 Subject: [PATCH 100/174] ci,viavi: not fail if timeout is reached --- tests/e2e/tests/viavi.py | 2 +- tests/e2e/tests/viavi/test_declaration.yml | 2 +- tests/e2e/tests/viavi/test_declaration_debug.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index 727f71c35b..00f3a6c237 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -398,7 +398,7 @@ def _test_viavi( except (TimeoutError, KeyboardInterrupt): logging.info("Stopping test due to timeout") viavi.stop_running_campaign() - pytest.fail("Viavi Test did not end in the expected timeout") + logging.warning("Viavi Test did not end in the expected timeout") finally: try: diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index e032ac35f5..cd67403d03 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -21,7 +21,7 @@ campaign_filename: &campaign_filename "C:\\ci\\CI 4x4 ORAN-FH-complete.xml" gnb_extra_commands: &gnb_extra_commands "ru_ofh --ta4_max 700 --ta4_min 10" -test_timeout: &test_timeout 2700 # 45 * 60 +test_timeout: &test_timeout 1800 # 30 * 60 tests: - campaign_filename: *campaign_filename diff --git a/tests/e2e/tests/viavi/test_declaration_debug.yml b/tests/e2e/tests/viavi/test_declaration_debug.yml index 993c626ac2..e201b67508 100644 --- a/tests/e2e/tests/viavi/test_declaration_debug.yml +++ b/tests/e2e/tests/viavi/test_declaration_debug.yml @@ -25,7 +25,7 @@ gnb_extra_commands: &gnb_extra_commands "" tests: - campaign_filename: *campaign_filename test_name: "32UE ideal UDP bidirectional" - test_timeout: 2700 # 45 * 60 + test_timeout: 1800 # 30 * 60 gnb_extra_commands: *gnb_extra_commands id: "32UE ideal UDP bidirectional - Debug" max_pdschs_per_slot: 1 From 6989d7d9583ab4607e541c25033de75b53dcc02a Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Mon, 23 Sep 2024 09:43:47 +0200 Subject: [PATCH 101/174] fapi: added SRS PDU to the loggers --- include/srsran/ran/srs/srs_configuration.h | 16 ++++++++++++++++ lib/fapi/loggers/message_loggers.cpp | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/srsran/ran/srs/srs_configuration.h b/include/srsran/ran/srs/srs_configuration.h index 83cd0ee616..63782368f8 100644 --- a/include/srsran/ran/srs/srs_configuration.h +++ b/include/srsran/ran/srs/srs_configuration.h @@ -29,6 +29,22 @@ enum class srs_group_or_sequence_hopping { neither, groupHopping, sequenceHoppin /// \brief \c resourceType, as per TS 38.331, "SRS-Resource". enum class srs_resource_type { aperiodic, semi_persistent, periodic }; +/// Convert SRS resource type to string. +inline std::string_view to_string(srs_resource_type res_type) +{ + switch (res_type) { + case srs_resource_type::aperiodic: + return "aperiodic"; + case srs_resource_type::semi_persistent: + return "semi-persistent"; + case srs_resource_type::periodic: + return "periodic"; + default: + break; + } + return "Invalid srs resource type"; +} + enum srs_nof_symbols : uint8_t { n1 = 1, n2 = 2, diff --git a/lib/fapi/loggers/message_loggers.cpp b/lib/fapi/loggers/message_loggers.cpp index a7dc477600..22ba25c19d 100644 --- a/lib/fapi/loggers/message_loggers.cpp +++ b/lib/fapi/loggers/message_loggers.cpp @@ -397,6 +397,26 @@ static void log_pucch_pdu(const ul_pucch_pdu& pdu, fmt::memory_buffer& buffer) } } +static void log_srs_pdu(const ul_srs_pdu& pdu, fmt::memory_buffer& buffer) +{ + fmt::format_to( + buffer, + "\n\t- SRS rnti={} bwp={}:{} nof_ports={} symb={}:{} config_idx={} comb=(size={} offset={} cyclic_shift={}) " + "freq_shift={} type={}", + pdu.rnti, + pdu.bwp_start, + pdu.bwp_size, + pdu.num_ant_ports, + pdu.time_start_position, + pdu.num_symbols, + pdu.config_index, + static_cast(pdu.comb_size), + pdu.comb_offset, + pdu.cyclic_shift, + pdu.frequency_shift, + to_string(pdu.resource_type)); +} + void srsran::fapi::log_ul_tti_request(const ul_tti_request_message& msg, srslog::basic_logger& logger) { fmt::memory_buffer buffer; @@ -414,6 +434,8 @@ void srsran::fapi::log_ul_tti_request(const ul_tti_request_message& msg, srslog: log_pusch_pdu(pdu.pusch_pdu, buffer); break; case fapi::ul_pdu_type::SRS: + log_srs_pdu(pdu.srs_pdu, buffer); + break; default: srsran_assert(0, "UL_TTI.request PDU type value ({}) not recognized.", static_cast(pdu.pdu_type)); } From 8fed02661246ce92ce66aef49a01f98560b395a8 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 20 Sep 2024 16:41:49 +0200 Subject: [PATCH 102/174] du_manager: synchronize lower prio UE executors in DU manager during traffic stop --- .../du_manager/du_ue/du_ue_controller_impl.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp index 7016b871d2..827ace0f21 100644 --- a/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp +++ b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp @@ -318,6 +318,23 @@ async_task du_ue_controller_impl::create_stop_traffic_task() async_task du_ue_controller_impl::run_in_ue_executor(unique_task task) { + return launch_async([this, task = std::move(task)](coro_context>& ctx) { + CORO_BEGIN(ctx); + + // Sync with UE control executor to run provided task. + CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); + task(); + CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); + + // Sync with remaining UE executors, as there might be still pending tasks dispatched to those. + CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.mac_ul_pdu_executor(ue_index))); + CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); + CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.f1u_dl_pdu_executor(ue_index))); + CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); + + CORO_RETURN(); + }); + return execute_and_continue_on_blocking( cfg.services.ue_execs.ctrl_executor(ue_index), cfg.services.du_mng_exec, std::move(task)); } From de55e153902326b197164a2d4191c02847884983 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 20 Sep 2024 17:16:36 +0200 Subject: [PATCH 103/174] du_manager: reuse ue traffic stop method during du ue manager shutdown --- .../du_manager/du_ue/du_ue_manager.cpp | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/lib/du/du_high/du_manager/du_ue/du_ue_manager.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_manager.cpp index a25d012ca8..2c38e2c9d7 100644 --- a/lib/du/du_high/du_manager/du_ue/du_ue_manager.cpp +++ b/lib/du/du_high/du_manager/du_ue/du_ue_manager.cpp @@ -153,36 +153,13 @@ async_task du_ue_manager::stop() proc_logger.log_proc_started(); - // Disconnect all UEs RLC->MAC buffer state adapters. - for (du_ue_controller_impl& u : ue_db) { - for (auto& srb : u.bearers.srbs()) { - srb.connector.rlc_tx_buffer_state_notif.disconnect(); - } - for (auto& drb_pair : u.bearers.drbs()) { - du_ue_drb& drb = *drb_pair.second; - drb.connector.rlc_tx_buffer_state_notif.disconnect(); - } - } - // Disconnect notifiers of all UEs bearers from within the ue_executors context. for (ue_it = ue_db.begin(); ue_it != ue_db.end(); ++ue_it) { - CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_it->ue_index))); - - for (auto& srb : ue_it->bearers.srbs()) { - srb.stop(); - } - - for (auto& drb_pair : ue_it->bearers.drbs()) { - du_ue_drb& drb = *drb_pair.second; - - drb.stop(); - } + CORO_AWAIT(ue_it->handle_traffic_stop_request()); } proc_logger.log_progress("All UEs are disconnected"); - CORO_AWAIT(execute_on_blocking(cfg.services.du_mng_exec)); - // Cancel all pending procedures. for (ue_it = ue_db.begin(); ue_it != ue_db.end(); ++ue_it) { eager_async_task ctrl_loop = ue_ctrl_loop[ue_it->ue_index].request_stop(); From 35b6b0901fff293655ef02d74732f7a9cf42ca1c Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 23 Sep 2024 16:39:29 +0200 Subject: [PATCH 104/174] du_manager: fix du_ue_controller --- .../du_high/du_manager/du_ue/du_ue_controller_impl.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp index 827ace0f21..074452720c 100644 --- a/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp +++ b/lib/du/du_high/du_manager/du_ue/du_ue_controller_impl.cpp @@ -324,17 +324,15 @@ async_task du_ue_controller_impl::run_in_ue_executor(unique_task task) // Sync with UE control executor to run provided task. CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); task(); - CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); + CORO_AWAIT(execute_on_blocking(cfg.services.du_mng_exec)); // Sync with remaining UE executors, as there might be still pending tasks dispatched to those. + // TODO: use when_all awaiter CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.mac_ul_pdu_executor(ue_index))); - CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); + CORO_AWAIT(execute_on_blocking(cfg.services.du_mng_exec)); CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.f1u_dl_pdu_executor(ue_index))); - CORO_AWAIT(execute_on_blocking(cfg.services.ue_execs.ctrl_executor(ue_index))); + CORO_AWAIT(execute_on_blocking(cfg.services.du_mng_exec)); CORO_RETURN(); }); - - return execute_and_continue_on_blocking( - cfg.services.ue_execs.ctrl_executor(ue_index), cfg.services.du_mng_exec, std::move(task)); } From 449b404720bdb80e0e9798c01721cf95a424b527 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 16 Sep 2024 15:17:13 +0100 Subject: [PATCH 105/174] cu_cp: remove loading from cu_cp impl --- apps/gnb/gnb.cpp | 3 +-- lib/cu_cp/cu_cp_impl.cpp | 44 +--------------------------------------- lib/cu_cp/cu_cp_impl.h | 2 -- 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index f97ab916dc..1e3d31d7ec 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -29,6 +29,7 @@ #include "gnb_appconfig_cli11_schema.h" #include "gnb_appconfig_translators.h" #include "gnb_appconfig_validators.h" +#include "gnb_appconfig_yaml_writer.h" #include "apps/services/worker_manager.h" @@ -42,8 +43,6 @@ // Include ThreadSanitizer (TSAN) options if thread sanitization is enabled. // This include is not unused - it helps prevent false alarms from the thread sanitizer. -#include "gnb_appconfig_yaml_writer.h" - #include "srsran/support/tsan_options.h" #include "apps/units/cu_cp/cu_cp_config_translators.h" diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 52c059c8db..8bf2804f61 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -67,7 +67,7 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : { assert_cu_cp_configuration_valid(cfg); - if (cfg.load_plugins && not load_plugins()) { + if (cfg.load_plugins) { logger.error("Could not load CU-CP plugins"); report_error("Could not load CU-CP plugins"); } @@ -99,15 +99,6 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : cu_cp_impl::~cu_cp_impl() { stop(); - - if (dl_handle != nullptr) { - if (::dlclose(dl_handle) != 0) { - char* err = ::dlerror(); - if (err != nullptr) { - logger.error("Failed to close DL handle: {}", err); - } - } - } } bool cu_cp_impl::start() @@ -148,39 +139,6 @@ void cu_cp_impl::stop() logger.info("CU-CP stopped successfully."); } -bool cu_cp_impl::load_plugins() -{ - char* err = nullptr; - std::string plugin_name = "libsrsran_plugin_ng_handover.so"; - - dl_handle = ::dlopen(plugin_name.c_str(), RTLD_NOW + RTLD_DEEPBIND + RTLD_GLOBAL); - if (dl_handle == nullptr) { - err = ::dlerror(); - if (err != nullptr) { - logger.error("Failed to load HO plugin {}: {}", plugin_name, err); - } else { - logger.error("Failed to load HO plugin {}", plugin_name); - } - return false; - } - - // Load symbol. - start_ho_prep_func = reinterpret_cast( - ::dlsym(dl_handle, "start_ngap_preparation_procedure_func")); - - // Handle an error loading the symbol. - if (start_ho_prep_func == nullptr) { - err = ::dlerror(); - if (err != nullptr) { - logger.error("Error loading symbol {}: {}\n", "start_ngap_preparation_procedure_func", err); - } else { - logger.error("Error loading symbol {}:\n", "start_ngap_preparation_procedure_func"); - } - return false; - } - return true; -} - ngap_message_handler* cu_cp_impl::get_ngap_message_handler(const plmn_identity& plmn) { return ngap_db->find_ngap(plmn); diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index ee40b8246c..08f5eb8d2b 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -205,9 +205,7 @@ class cu_cp_impl final : public cu_cp, std::atomic stopped{false}; // Plug-ins - [[nodiscard]] bool load_plugins(); start_ngap_handover_preparation_procedure_func start_ho_prep_func = nullptr; - void* dl_handle = nullptr; }; } // namespace srs_cu_cp From af935d87860c2f19ebe8cac9f52272612ada3c6f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 16 Sep 2024 15:17:49 +0100 Subject: [PATCH 106/174] support: added helper to load symbols from libraries --- apps/gnb/gnb.cpp | 19 ++++++ apps/units/cu_cp/cu_cp_builder.h | 3 +- include/srsran/cu_cp/cu_cp_configuration.h | 3 +- include/srsran/support/dl_manager.h | 33 ++++++++++ lib/cu_cp/cu_cp_impl.cpp | 9 ++- lib/support/CMakeLists.txt | 1 + lib/support/dl_manager.cpp | 76 ++++++++++++++++++++++ 7 files changed, 137 insertions(+), 7 deletions(-) create mode 100644 include/srsran/support/dl_manager.h create mode 100644 lib/support/dl_manager.cpp diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 1e3d31d7ec..add97730e6 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -9,6 +9,7 @@ */ #include "srsran/support/cpu_features.h" +#include "srsran/support/dl_manager.h" #include "srsran/support/event_tracing.h" #include "srsran/support/signal_handling.h" #include "srsran/support/versioning/build_info.h" @@ -373,6 +374,21 @@ int main(int argc, char** argv) cu_cp_dependencies.cu_cp_e2_exec = workers.cu_cp_e2_exec; cu_cp_dependencies.timers = cu_timers; + // Load CU-CP plugins if enabled + dl_manager ng_handover_plugin(gnb_logger); + if (cu_cp_config.load_plugins) { + if (not ng_handover_plugin.open("libsrsran_plugin_ng_handover.so")) { + gnb_logger.error("Could not open NG Handover plugin"); + return -1; + } + expected ng_ho_func = ng_handover_plugin.load_symbol("start_ngap_preparation_procedure_func"); + if (not ng_ho_func) { + gnb_logger.error("Could not open NG Handover function pointer"); + return -1; + } + cu_cp_dependencies.start_ng_handover_func = ng_ho_func.value(); + } + // Create N2 Client Gateways. cu_cp_dependencies.n2_clients.push_back(srs_cu_cp::create_n2_connection_client(generate_n2_client_config( cu_cp_config.amf_config.no_core, cu_cp_config.amf_config.amf, *cu_cp_dlt_pcaps.ngap, *epoll_broker))); @@ -489,6 +505,9 @@ int main(int argc, char** argv) workers.stop(); gnb_logger.info("Executors closed successfully."); + if (cu_cp_config.load_plugins and not ng_handover_plugin.close()) { + gnb_logger.error("Could not close plugin manager"); + } srslog::flush(); return 0; diff --git a/apps/units/cu_cp/cu_cp_builder.h b/apps/units/cu_cp/cu_cp_builder.h index 6dc94cf164..97b8354e5b 100644 --- a/apps/units/cu_cp/cu_cp_builder.h +++ b/apps/units/cu_cp/cu_cp_builder.h @@ -27,7 +27,8 @@ struct cu_cp_build_dependencies { task_executor* cu_cp_executor = nullptr; task_executor* cu_cp_e2_exec = nullptr; std::vector> n2_clients; - timer_manager* timers = nullptr; + timer_manager* timers = nullptr; + void* start_ng_handover_func = nullptr; }; /// Wraps the CU-CP and its supported application commands. diff --git a/include/srsran/cu_cp/cu_cp_configuration.h b/include/srsran/cu_cp/cu_cp_configuration.h index dd16ea4fbc..f2888984a6 100644 --- a/include/srsran/cu_cp/cu_cp_configuration.h +++ b/include/srsran/cu_cp/cu_cp_configuration.h @@ -115,7 +115,8 @@ struct cu_cp_configuration { /// Parameters related with CU-CP metrics. metrics_params metrics; /// Plugins parameters - bool load_plugins; + bool load_plugins; + void* start_ng_ho_func = nullptr; /// Timers, executors, and other services used by the CU-CP. service_params services; }; diff --git a/include/srsran/support/dl_manager.h b/include/srsran/support/dl_manager.h new file mode 100644 index 0000000000..0ab21e683b --- /dev/null +++ b/include/srsran/support/dl_manager.h @@ -0,0 +1,33 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/adt/expected.h" +#include "srsran/srslog/logger.h" + +namespace srsran { +class dl_manager +{ +public: + explicit dl_manager(srslog::basic_logger& logger_); + + [[nodiscard]] bool open(const std::string& dl_name); + + expected load_symbol(const std::string& symbol_name); + + [[nodiscard]] bool close(); + +private: + void* dl_handle = nullptr; + srslog::basic_logger& logger; +}; + +} // namespace srsran diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 8bf2804f61..59f8279e4b 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -67,17 +67,16 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : { assert_cu_cp_configuration_valid(cfg); - if (cfg.load_plugins) { - logger.error("Could not load CU-CP plugins"); - report_error("Could not load CU-CP plugins"); - } - // connect event notifiers to layers ngap_cu_cp_ev_notifier.connect_cu_cp(*this, paging_handler); mobility_manager_ev_notifier.connect_cu_cp(get_cu_cp_mobility_manager_handler()); e1ap_ev_notifier.connect_cu_cp(get_cu_cp_e1ap_handler()); rrc_du_cu_cp_notifier.connect_cu_cp(get_cu_cp_measurement_config_handler()); + if (cfg.start_ng_ho_func != nullptr) { + start_ho_prep_func = reinterpret_cast(cfg.start_ng_ho_func); + } + ngap_db = std::make_unique(ngap_repository_config{ cfg, get_cu_cp_ngap_handler(), paging_handler, start_ho_prep_func, srslog::fetch_basic_logger("CU-CP")}); diff --git a/lib/support/CMakeLists.txt b/lib/support/CMakeLists.txt index 7f0874061e..2c799e4a7c 100644 --- a/lib/support/CMakeLists.txt +++ b/lib/support/CMakeLists.txt @@ -27,6 +27,7 @@ set(SOURCES sysinfo.cpp timers.cpp math_utils.cpp + dl_manager.cpp ) add_library(srsran_support STATIC ${SOURCES}) diff --git a/lib/support/dl_manager.cpp b/lib/support/dl_manager.cpp new file mode 100644 index 0000000000..64e5dcd505 --- /dev/null +++ b/lib/support/dl_manager.cpp @@ -0,0 +1,76 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#include "srsran/support/dl_manager.h" +#include +#include + +using namespace srsran; + +dl_manager::dl_manager(srslog::basic_logger& logger_) : logger(logger_) {} + +bool dl_manager::open(const std::string& dl_name) +{ + char* err = nullptr; + + dl_handle = ::dlopen(dl_name.c_str(), RTLD_NOW + RTLD_DEEPBIND + RTLD_GLOBAL); + if (dl_handle == nullptr) { + err = ::dlerror(); + if (err != nullptr) { + logger.error("Failed to load library {}: {}", dl_name, err); + } else { + logger.error("Failed to load library {}", dl_name); + } + return false; + } + logger.debug("Opened library: {}", dl_name); + return true; +} + +expected dl_manager::load_symbol(const std::string& symbol_name) +{ + if (dl_handle == nullptr) { + return make_unexpected(default_error_t{}); + } + + void* symb = ::dlsym(dl_handle, symbol_name.c_str()); + + // Handle an error loading the symbol. + char* err = nullptr; + if (symb == nullptr) { + err = ::dlerror(); + if (err != nullptr) { + logger.error("Error loading symbol {}: {}\n", "start_ngap_preparation_procedure_func", err); + } else { + logger.error("Error loading symbol {}:\n", "start_ngap_preparation_procedure_func"); + } + return make_unexpected(default_error_t{}); + } + logger.debug("Loaded symbol: {}", symbol_name); + return symb; +} + +bool dl_manager::close() +{ + if (dl_handle == nullptr) { + return false; + } + + if (::dlclose(dl_handle) != 0) { + char* err = ::dlerror(); + if (err != nullptr) { + logger.error("Failed to close DL handle: {}", err); + } else { + logger.error("Failed to close DL handle"); + } + return false; + } + logger.debug("Closed library"); + return true; +} From 853d7a6b2b0467cc93af0dd0ced920d46786b2a3 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 17 Sep 2024 17:33:12 +0100 Subject: [PATCH 107/174] cu_cp: fix passing func pointer for starting NG HO --- apps/gnb/gnb.cpp | 2 +- apps/units/cu_cp/cu_cp_builder.h | 3 +-- apps/units/cu_cp/cu_cp_config_translators.cpp | 3 ++- apps/units/cu_cp/cu_cp_unit_config.h | 2 ++ include/srsran/cu_cp/cu_cp_configuration.h | 10 ++++++++-- lib/cu_cp/cu_cp_impl.cpp | 4 ++-- lib/cu_cp/mobility_manager/mobility_manager_impl.cpp | 2 +- 7 files changed, 17 insertions(+), 9 deletions(-) diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index add97730e6..b830ca5999 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -386,7 +386,7 @@ int main(int argc, char** argv) gnb_logger.error("Could not open NG Handover function pointer"); return -1; } - cu_cp_dependencies.start_ng_handover_func = ng_ho_func.value(); + cu_cp_config.start_ng_ho_func = ng_ho_func.value(); } // Create N2 Client Gateways. diff --git a/apps/units/cu_cp/cu_cp_builder.h b/apps/units/cu_cp/cu_cp_builder.h index 97b8354e5b..6dc94cf164 100644 --- a/apps/units/cu_cp/cu_cp_builder.h +++ b/apps/units/cu_cp/cu_cp_builder.h @@ -27,8 +27,7 @@ struct cu_cp_build_dependencies { task_executor* cu_cp_executor = nullptr; task_executor* cu_cp_e2_exec = nullptr; std::vector> n2_clients; - timer_manager* timers = nullptr; - void* start_ng_handover_func = nullptr; + timer_manager* timers = nullptr; }; /// Wraps the CU-CP and its supported application commands. diff --git a/apps/units/cu_cp/cu_cp_config_translators.cpp b/apps/units/cu_cp/cu_cp_config_translators.cpp index f1a1629968..cb2e651202 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.cpp +++ b/apps/units/cu_cp/cu_cp_config_translators.cpp @@ -388,7 +388,8 @@ srs_cu_cp::cu_cp_configuration srsran::generate_cu_cp_config(const cu_cp_unit_co out_cfg.f1ap.json_log_enabled = cu_cfg.loggers.f1ap_json_enabled; // Plugins - out_cfg.load_plugins = cu_cfg.load_plugins; + out_cfg.plugin.load_plugins = cu_cfg.load_plugins; + out_cfg.plugin.start_ng_ho_func = cu_cfg.start_ng_ho_func; // Convert appconfig's cell list into cell manager type. for (const auto& app_cfg_item : cu_cfg.mobility_config.cells) { diff --git a/apps/units/cu_cp/cu_cp_unit_config.h b/apps/units/cu_cp/cu_cp_unit_config.h index 0b2a5f748c..eae8854edb 100644 --- a/apps/units/cu_cp/cu_cp_unit_config.h +++ b/apps/units/cu_cp/cu_cp_unit_config.h @@ -264,6 +264,8 @@ struct cu_cp_unit_config { int inactivity_timer = 120; /// Load enterprise plugins. bool load_plugins = false; + /// Function pointer to start NG handover from plugin + void* start_ng_ho_func; /// PDU session setup timeout in seconds (must be larger than T310). unsigned pdu_session_setup_timeout = 3; /// Loggers configuration. diff --git a/include/srsran/cu_cp/cu_cp_configuration.h b/include/srsran/cu_cp/cu_cp_configuration.h index f2888984a6..fe7abbb773 100644 --- a/include/srsran/cu_cp/cu_cp_configuration.h +++ b/include/srsran/cu_cp/cu_cp_configuration.h @@ -94,6 +94,13 @@ struct cu_cp_configuration { std::chrono::seconds statistics_report_period{1}; }; + struct plugin_params { + /// Try to load CU-CP plugins. + bool load_plugins; + /// Loaded function pointer to trigger NG Handover + void* start_ng_ho_func = nullptr; + }; + /// NG-RAN node parameters. ran_node_configuration node; /// Parameters to determine the admission of new CU-UP, DU and UE connections. @@ -115,8 +122,7 @@ struct cu_cp_configuration { /// Parameters related with CU-CP metrics. metrics_params metrics; /// Plugins parameters - bool load_plugins; - void* start_ng_ho_func = nullptr; + plugin_params plugin; /// Timers, executors, and other services used by the CU-CP. service_params services; }; diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 59f8279e4b..817ee89608 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -73,8 +73,8 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : e1ap_ev_notifier.connect_cu_cp(get_cu_cp_e1ap_handler()); rrc_du_cu_cp_notifier.connect_cu_cp(get_cu_cp_measurement_config_handler()); - if (cfg.start_ng_ho_func != nullptr) { - start_ho_prep_func = reinterpret_cast(cfg.start_ng_ho_func); + if (cfg.plugin.start_ng_ho_func != nullptr) { + start_ho_prep_func = reinterpret_cast(cfg.plugin.start_ng_ho_func); } ngap_db = std::make_unique(ngap_repository_config{ diff --git a/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp b/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp index 9f5ac201dc..941e0831d3 100644 --- a/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp +++ b/lib/cu_cp/mobility_manager/mobility_manager_impl.cpp @@ -140,7 +140,7 @@ void mobility_manager::handle_inter_cu_handover(ue_index_t source_ue_index nr_cell_identity target_nci) { if (not cfg.enable_ng_handover) { - logger.error("ue={}: trying to use NG handover without HO plugin loaded.", source_ue_index); + logger.warning("ue={}: trying to use NG handover without HO plugin loaded.", source_ue_index); return; } From 3024cccfd70d7fb5f4fd3f2b69339488d8768224 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 20 Sep 2024 16:46:54 +0100 Subject: [PATCH 108/174] support: address review comments for dynlink_manager - Rename dl_manager to dynlink_manager - Added static create function for RAII of handle - Store dl_name for better logging --- apps/gnb/gnb.cpp | 12 +++---- .../{dl_manager.h => dynlink_manager.h} | 16 +++++---- lib/support/CMakeLists.txt | 2 +- .../{dl_manager.cpp => dynlink_manager.cpp} | 35 ++++++++++++++----- 4 files changed, 41 insertions(+), 24 deletions(-) rename include/srsran/support/{dl_manager.h => dynlink_manager.h} (52%) rename lib/support/{dl_manager.cpp => dynlink_manager.cpp} (60%) diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index b830ca5999..875f749134 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -9,7 +9,7 @@ */ #include "srsran/support/cpu_features.h" -#include "srsran/support/dl_manager.h" +#include "srsran/support/dynlink_manager.h" #include "srsran/support/event_tracing.h" #include "srsran/support/signal_handling.h" #include "srsran/support/versioning/build_info.h" @@ -375,13 +375,14 @@ int main(int argc, char** argv) cu_cp_dependencies.timers = cu_timers; // Load CU-CP plugins if enabled - dl_manager ng_handover_plugin(gnb_logger); + std::optional ng_handover_plugin = + cu_cp_config.load_plugins ? dynlink_manager::create("libsrsran_plugin_ng_handover.so", gnb_logger) : std::nullopt; if (cu_cp_config.load_plugins) { - if (not ng_handover_plugin.open("libsrsran_plugin_ng_handover.so")) { + if (not ng_handover_plugin) { gnb_logger.error("Could not open NG Handover plugin"); return -1; } - expected ng_ho_func = ng_handover_plugin.load_symbol("start_ngap_preparation_procedure_func"); + expected ng_ho_func = ng_handover_plugin->load_symbol("start_ngap_preparation_procedure_func"); if (not ng_ho_func) { gnb_logger.error("Could not open NG Handover function pointer"); return -1; @@ -505,9 +506,6 @@ int main(int argc, char** argv) workers.stop(); gnb_logger.info("Executors closed successfully."); - if (cu_cp_config.load_plugins and not ng_handover_plugin.close()) { - gnb_logger.error("Could not close plugin manager"); - } srslog::flush(); return 0; diff --git a/include/srsran/support/dl_manager.h b/include/srsran/support/dynlink_manager.h similarity index 52% rename from include/srsran/support/dl_manager.h rename to include/srsran/support/dynlink_manager.h index 0ab21e683b..da7612bc25 100644 --- a/include/srsran/support/dl_manager.h +++ b/include/srsran/support/dynlink_manager.h @@ -14,19 +14,21 @@ #include "srsran/srslog/logger.h" namespace srsran { -class dl_manager +class dynlink_manager { public: - explicit dl_manager(srslog::basic_logger& logger_); + static std::optional create(const std::string& dl_name, srslog::basic_logger& logger_); + expected load_symbol(const std::string& symbol_name); - [[nodiscard]] bool open(const std::string& dl_name); - - expected load_symbol(const std::string& symbol_name); - - [[nodiscard]] bool close(); + ~dynlink_manager(); private: + explicit dynlink_manager(const std::string& dl_name_, srslog::basic_logger& logger_); + [[nodiscard]] bool open(); + bool close(); + void* dl_handle = nullptr; + std::string dl_name; srslog::basic_logger& logger; }; diff --git a/lib/support/CMakeLists.txt b/lib/support/CMakeLists.txt index 2c799e4a7c..8988a3e9e1 100644 --- a/lib/support/CMakeLists.txt +++ b/lib/support/CMakeLists.txt @@ -27,7 +27,7 @@ set(SOURCES sysinfo.cpp timers.cpp math_utils.cpp - dl_manager.cpp + dynlink_manager.cpp ) add_library(srsran_support STATIC ${SOURCES}) diff --git a/lib/support/dl_manager.cpp b/lib/support/dynlink_manager.cpp similarity index 60% rename from lib/support/dl_manager.cpp rename to lib/support/dynlink_manager.cpp index 64e5dcd505..07eb64394d 100644 --- a/lib/support/dl_manager.cpp +++ b/lib/support/dynlink_manager.cpp @@ -7,15 +7,32 @@ * the distribution. * */ -#include "srsran/support/dl_manager.h" +#include "srsran/support/dynlink_manager.h" #include #include using namespace srsran; -dl_manager::dl_manager(srslog::basic_logger& logger_) : logger(logger_) {} +std::optional dynlink_manager::create(const std::string& dl_name, srslog::basic_logger& logger) +{ + dynlink_manager mng(dl_name, logger); + if (not mng.open()) { + return {}; + } + return mng; +} + +dynlink_manager::dynlink_manager(const std::string& dl_name_, srslog::basic_logger& logger_) : + dl_name(dl_name_), logger(logger_) +{ +} + +dynlink_manager::~dynlink_manager() +{ + close(); +} -bool dl_manager::open(const std::string& dl_name) +bool dynlink_manager::open() { char* err = nullptr; @@ -33,7 +50,7 @@ bool dl_manager::open(const std::string& dl_name) return true; } -expected dl_manager::load_symbol(const std::string& symbol_name) +expected dynlink_manager::load_symbol(const std::string& symbol_name) { if (dl_handle == nullptr) { return make_unexpected(default_error_t{}); @@ -46,9 +63,9 @@ expected dl_manager::load_symbol(const std::string& symbol_name) if (symb == nullptr) { err = ::dlerror(); if (err != nullptr) { - logger.error("Error loading symbol {}: {}\n", "start_ngap_preparation_procedure_func", err); + logger.error("Error loading symbol {} in {}: {}\n", symbol_name, dl_name, err); } else { - logger.error("Error loading symbol {}:\n", "start_ngap_preparation_procedure_func"); + logger.error("Error loading symbol {} in {}:\n", symbol_name, dl_name); } return make_unexpected(default_error_t{}); } @@ -56,7 +73,7 @@ expected dl_manager::load_symbol(const std::string& symbol_name) return symb; } -bool dl_manager::close() +bool dynlink_manager::close() { if (dl_handle == nullptr) { return false; @@ -65,9 +82,9 @@ bool dl_manager::close() if (::dlclose(dl_handle) != 0) { char* err = ::dlerror(); if (err != nullptr) { - logger.error("Failed to close DL handle: {}", err); + logger.error("Failed to close dynamic link handle: {}", err); } else { - logger.error("Failed to close DL handle"); + logger.error("Failed to close dynamic link handle"); } return false; } From 7b7b5e49f1ee3afa89a55886a9d05916895960f4 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 18 Sep 2024 12:36:00 +0100 Subject: [PATCH 109/174] rlc: add RLC TX benchmark This is an intial attempt to benchmark pull_pdu(). Currently, this is done without any segmentation. All SDUs are pushed at benchmark initialzation, and so is the PDU space reservation. --- tests/benchmarks/rlc/CMakeLists.txt | 4 + tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp | 190 +++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp diff --git a/tests/benchmarks/rlc/CMakeLists.txt b/tests/benchmarks/rlc/CMakeLists.txt index ed61949109..552dfc51f3 100644 --- a/tests/benchmarks/rlc/CMakeLists.txt +++ b/tests/benchmarks/rlc/CMakeLists.txt @@ -17,3 +17,7 @@ add_test(rlc_handle_status_report rlc_handle_status_report) add_executable(rlc_am_rx_benchmark rlc_am_rx_benchmark.cpp) target_link_libraries(rlc_am_rx_benchmark srsran_rlc srslog pdcp_test_doubles) add_test(rlc_am_rx_benchmark rlc_am_rx_benchmark) + +add_executable(rlc_am_tx_benchmark rlc_am_tx_benchmark.cpp) +target_link_libraries(rlc_am_tx_benchmark srsran_rlc srslog pdcp_test_doubles) +add_test(rlc_am_tx_benchmark rlc_am_tx_benchmark) diff --git a/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp new file mode 100644 index 0000000000..d75b97ceca --- /dev/null +++ b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp @@ -0,0 +1,190 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "lib/rlc/rlc_tx_am_entity.h" +#include "tests/test_doubles/pdcp/pdcp_pdu_generator.h" +#include "srsran/support/benchmark_utils.h" +#include "srsran/support/executors/manual_task_worker.h" +#include + +using namespace srsran; + +/// Mocking class of the surrounding layers invoked by the RLC AM Tx entity. +class rlc_tx_am_test_frame : public rlc_tx_upper_layer_data_notifier, + public rlc_tx_upper_layer_control_notifier, + public rlc_tx_lower_layer_notifier, + public rlc_rx_am_status_provider, + public rlc_metrics_notifier +{ +public: + rlc_am_sn_size sn_size; + rlc_am_status_pdu status; + bool status_required = false; + uint32_t bsr = 0; + uint32_t bsr_count = 0; + uint32_t max_retx_count = 0; + + rlc_tx_am_test_frame(rlc_am_sn_size sn_size_) : sn_size(sn_size_), status(sn_size_) {} + + // rlc_tx_upper_layer_data_notifier interface + void on_transmitted_sdu(uint32_t max_tx_pdcp_sn, uint32_t queue_free_bytes) override {} + void on_delivered_sdu(uint32_t max_deliv_pdcp_sn) override {} + void on_retransmitted_sdu(uint32_t max_retx_pdcp_sn) override {} + void on_delivered_retransmitted_sdu(uint32_t max_deliv_retx_pdcp_sn) override {} + + // rlc_tx_upper_layer_control_notifier interface + void on_protocol_failure() override {} + void on_max_retx() override {} + + // rlc_tx_buffer_state_update_notifier interface + void on_buffer_state_update(unsigned bsr_) override {} + + // rlc_rx_am_status_provider interface + rlc_am_status_pdu& get_status_pdu() override { return status; } + uint32_t get_status_pdu_length() override { return status.get_packed_size(); } + bool status_report_required() override { return status_required; } + + // rlc_metrics_notifier + void report_metrics(const rlc_metrics& metrics) override {} +}; + +struct bench_params { + unsigned nof_repetitions = 10000; + unsigned sdu_size = 1500; +}; + +static void usage(const char* prog, const bench_params& params) +{ + fmt::print("Usage: {} [-R repetitions] [-s silent]\n", prog); + fmt::print("\t-R Repetitions [Default {}]\n", params.nof_repetitions); + fmt::print("\t-s SDU size [Default {}]\n", params.sdu_size); + fmt::print("\t-h Show this message\n"); +} + +static void parse_args(int argc, char** argv, bench_params& params) +{ + int opt = 0; + while ((opt = getopt(argc, argv, "R:s:p:h")) != -1) { + switch (opt) { + case 'R': + params.nof_repetitions = std::strtol(optarg, nullptr, 10); + break; + case 's': + params.sdu_size = std::strtol(optarg, nullptr, 10); + break; + case 'h': + default: + usage(argv[0], params); + exit(0); + } + } +} + +std::vector> +push_sdus(bench_params params, const rlc_tx_am_config& config, rlc_tx_am_entity* rlc_tx) +{ + timer_manager timers; + manual_task_worker pcell_worker{128}; + manual_task_worker ue_worker{128}; + + // Make PDUs + std::vector> pdus; + + // Prepare SDU list for benchmark + int num_sdus = params.nof_repetitions; // +1 to expire t_reassembly on setup + int num_bytes = params.sdu_size; + pdus.resize(num_sdus); + for (int i = 0; i < num_sdus; i++) { + byte_buffer sdu = test_helpers::create_pdcp_pdu(config.pdcp_sn_len, /* is_srb = */ false, i, num_bytes, i); + rlc_tx->handle_sdu(std::move(sdu), false); + pdus[i].resize(params.sdu_size + 5); // reserve max possible header + } + + return pdus; +} + +void benchmark_tx_pdu(const bench_params& params) +{ + fmt::memory_buffer buffer; + fmt::format_to(buffer, "Benchmark RLC AM TX PDUs"); + std::unique_ptr bm = std::make_unique(to_c_str(buffer), params.nof_repetitions); + + // Set Tx config + rlc_tx_am_config config; + config.sn_field_length = rlc_am_sn_size::size18bits; + config.pdcp_sn_len = pdcp_sn_size::size18bits; + config.t_poll_retx = 45; + config.max_retx_thresh = 4; + config.poll_pdu = 4; + config.poll_byte = 25; + config.queue_size = 4096; + config.queue_size_bytes = 4096 * 1507; + config.max_window = 0; + + auto tester = std::make_unique(config.sn_field_length); + + timer_manager timers; + manual_task_worker pcell_worker{128}; + manual_task_worker ue_worker{128}; + + null_rlc_pcap pcap; + + auto metrics_agg = std::make_unique( + gnb_du_id_t{}, du_ue_index_t{}, rb_id_t{}, timer_duration{0}, tester.get(), ue_worker); + + // Create RLC AM TX entity + auto rlc_tx = std::make_unique(gnb_du_id_t::min, + du_ue_index_t::MIN_DU_UE_INDEX, + drb_id_t::drb1, + config, + *tester, + *tester, + *tester, + *metrics_agg, + pcap, + pcell_worker, + ue_worker, + timers); + + // Bind AM Rx/Tx interconnect + rlc_tx->set_status_provider(tester.get()); + + std::vector> pdus = push_sdus(params, config, rlc_tx.get()); + + unsigned i = 0; + + // Push first PDU and expire reassembly timer to advance rx_highest_status + auto measure = [&rlc_tx, &i, &pdus]() mutable { + rlc_tx->pull_pdu(pdus[i]); + i++; + }; + bm->new_measure("RX RLC AM PDU", 1500 * 8, measure); + + // Output results. + bm->print_percentiles_time(); + bm->print_percentiles_throughput(" bps"); +} + +int main(int argc, char** argv) +{ + srslog::fetch_basic_logger("RLC").set_level(srslog::basic_levels::error); + + srslog::init(); + + bench_params params{}; + parse_args(argc, argv, params); + + // Setup size of byte buffer pool. + init_byte_buffer_segment_pool(524288); + + benchmark_tx_pdu(params); + + srslog::flush(); +} From 5cf76686a64cb1c91c3588244c3e005ec8913145 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 18 Sep 2024 12:58:16 +0100 Subject: [PATCH 110/174] rlc: fix queue size in RLC TX benchmark --- tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp index d75b97ceca..613ca9644e 100644 --- a/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp +++ b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp @@ -98,7 +98,7 @@ push_sdus(bench_params params, const rlc_tx_am_config& config, rlc_tx_am_entity* std::vector> pdus; // Prepare SDU list for benchmark - int num_sdus = params.nof_repetitions; // +1 to expire t_reassembly on setup + int num_sdus = params.nof_repetitions; int num_bytes = params.sdu_size; pdus.resize(num_sdus); for (int i = 0; i < num_sdus; i++) { @@ -124,8 +124,8 @@ void benchmark_tx_pdu(const bench_params& params) config.max_retx_thresh = 4; config.poll_pdu = 4; config.poll_byte = 25; - config.queue_size = 4096; - config.queue_size_bytes = 4096 * 1507; + config.queue_size = params.nof_repetitions; + config.queue_size_bytes = params.nof_repetitions * 1507; config.max_window = 0; auto tester = std::make_unique(config.sn_field_length); @@ -165,7 +165,7 @@ void benchmark_tx_pdu(const bench_params& params) rlc_tx->pull_pdu(pdus[i]); i++; }; - bm->new_measure("RX RLC AM PDU", 1500 * 8, measure); + bm->new_measure("TX RLC AM PDU", params.sdu_size * 8, measure); // Output results. bm->print_percentiles_time(); @@ -174,7 +174,7 @@ void benchmark_tx_pdu(const bench_params& params) int main(int argc, char** argv) { - srslog::fetch_basic_logger("RLC").set_level(srslog::basic_levels::error); + srslog::fetch_basic_logger("RLC").set_level(srslog::basic_levels::warning); srslog::init(); From 3a4859c5b0ef78aa8b7843a27cfc86bbc41d8219 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 18 Sep 2024 17:26:02 +0100 Subject: [PATCH 111/174] rlc: print RLC metrics and pre-reserve timer commands --- include/srsran/support/benchmark_utils.h | 12 ++++++++++++ lib/support/timers.cpp | 2 ++ tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp | 10 ++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/include/srsran/support/benchmark_utils.h b/include/srsran/support/benchmark_utils.h index 4a944e5b63..8fd0a05406 100644 --- a/include/srsran/support/benchmark_utils.h +++ b/include/srsran/support/benchmark_utils.h @@ -166,6 +166,18 @@ class benchmarker #endif } + /// Get the total measured execution time in nanoseconds. + uint64_t get_total_meas_time_ns() const + { + uint64_t total = 0; + for (const benchmark_result& res : benchmark_results) { + for (uint64_t mes : res.measurements) { + total += mes; + } + } + return total; + } + /// Prints the time execution measurements in nanoseconds. void print_percentiles_time(const std::string& units = "nanoseconds", double scaling = 1.0) const { diff --git a/lib/support/timers.cpp b/lib/support/timers.cpp index df617f5a71..fbee9cbb00 100644 --- a/lib/support/timers.cpp +++ b/lib/support/timers.cpp @@ -73,6 +73,8 @@ timer_manager::timer_manager(size_t capacity) : logger(srslog::fetch_basic_logge for (auto i = timer_list.rbegin(), e = timer_list.rend(); i != e; ++i) { free_list.emplace_back(i->frontend.get()); } + pending_cmds.reserve(16384); + cmds_to_process.reserve(16384); } void timer_manager::tick() diff --git a/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp index 613ca9644e..685c14f7f4 100644 --- a/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp +++ b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp @@ -137,7 +137,7 @@ void benchmark_tx_pdu(const bench_params& params) null_rlc_pcap pcap; auto metrics_agg = std::make_unique( - gnb_du_id_t{}, du_ue_index_t{}, rb_id_t{}, timer_duration{0}, tester.get(), ue_worker); + gnb_du_id_t{}, du_ue_index_t{}, rb_id_t{}, timer_duration{1}, tester.get(), ue_worker); // Create RLC AM TX entity auto rlc_tx = std::make_unique(gnb_du_id_t::min, @@ -161,7 +161,7 @@ void benchmark_tx_pdu(const bench_params& params) unsigned i = 0; // Push first PDU and expire reassembly timer to advance rx_highest_status - auto measure = [&rlc_tx, &i, &pdus]() mutable { + auto measure = [&rlc_tx, &i, &pdus]() { rlc_tx->pull_pdu(pdus[i]); i++; }; @@ -170,6 +170,12 @@ void benchmark_tx_pdu(const bench_params& params) // Output results. bm->print_percentiles_time(); bm->print_percentiles_throughput(" bps"); + + uint64_t bm_duration_ns = bm->get_total_meas_time_ns(); + std::chrono::nanoseconds bm_duration(bm_duration_ns); + rlc_tx_metrics tx_metrics = rlc_tx->get_metrics(); + fmt::print("RLC TX metrics: {}\n", + format_rlc_tx_metrics(std::chrono::duration_cast(bm_duration), tx_metrics)); } int main(int argc, char** argv) From b16bd1a7cc4e06f52fa54bd4c6bf99a95132fdc7 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 19 Sep 2024 14:50:59 +0100 Subject: [PATCH 112/174] rlc: reduce size of histogram bin in metrics --- include/srsran/rlc/rlc_tx_metrics.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/srsran/rlc/rlc_tx_metrics.h b/include/srsran/rlc/rlc_tx_metrics.h index b74ee8411c..a4c90a0230 100644 --- a/include/srsran/rlc/rlc_tx_metrics.h +++ b/include/srsran/rlc/rlc_tx_metrics.h @@ -90,7 +90,7 @@ struct rlc_tx_metrics_lower { // Histogram of pull pdus static constexpr unsigned pdu_latency_hist_bins = 8; - static constexpr unsigned nof_usec_per_bin = 10; + static constexpr unsigned nof_usec_per_bin = 1; std::array pdu_latency_hist_ns; uint32_t max_pdu_latency_ns; From d3d2d122a185208b0045a20907fcba948333e9e3 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 20 Sep 2024 15:23:27 +0100 Subject: [PATCH 113/174] rlc: add latency metrics to json metrics --- .../metrics/du_high_rlc_metrics_consumers.cpp | 29 ++++++++++++++++++- lib/support/timers.cpp | 5 ++-- tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp | 3 +- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/apps/units/flexible_du/du_high/metrics/du_high_rlc_metrics_consumers.cpp b/apps/units/flexible_du/du_high/metrics/du_high_rlc_metrics_consumers.cpp index b2d329db17..2eaf8fc260 100644 --- a/apps/units/flexible_du/du_high/metrics/du_high_rlc_metrics_consumers.cpp +++ b/apps/units/flexible_du/du_high/metrics/du_high_rlc_metrics_consumers.cpp @@ -29,6 +29,18 @@ DECLARE_METRIC("num_discarded_sdus", metric_tx_num_discarded_sdus, uint32_t, "") DECLARE_METRIC("num_discard_failures", metric_tx_num_discard_failures, uint32_t, ""); DECLARE_METRIC("num_pdus", metric_tx_num_pdus, uint32_t, ""); DECLARE_METRIC("num_pdu_bytes", metric_tx_num_pdu_bytes, uint32_t, ""); +DECLARE_METRIC("sum_sdu_latency_us", metric_tx_sum_sdu_latency_us, uint32_t, ""); +DECLARE_METRIC("sum_pdu_latency_ns", metric_tx_sum_pdu_latency_ns, uint32_t, ""); +DECLARE_METRIC("max_pdu_latency_ns", metric_tx_max_pdu_latency_ns, uint32_t, ""); +DECLARE_METRIC("pull_latency_bin_start_usec", metric_tx_pull_latency_bin_start_usec, unsigned, ""); +DECLARE_METRIC("pull_latency_bin_count", metric_tx_pull_latency_bin_count, unsigned, ""); +DECLARE_METRIC_SET("pull_latency_bin", + metric_tx_pull_latency_bin, + metric_tx_pull_latency_bin_start_usec, + metric_tx_pull_latency_bin_count); +DECLARE_METRIC_LIST("pull_latency_histogram", + metric_tx_pull_latency_histogram, + std::vector); DECLARE_METRIC_SET("tx", mset_drb_tx_container, metric_tx_num_sdus, @@ -37,7 +49,11 @@ DECLARE_METRIC_SET("tx", metric_tx_num_discarded_sdus, metric_tx_num_discard_failures, metric_tx_num_pdus, - metric_tx_num_pdu_bytes); + metric_tx_num_pdu_bytes, + metric_tx_sum_sdu_latency_us, + metric_tx_sum_pdu_latency_ns, + metric_tx_max_pdu_latency_ns, + metric_tx_pull_latency_histogram); DECLARE_METRIC("num_sdus", metric_rx_num_sdus, uint32_t, ""); DECLARE_METRIC("num_sdu_bytes", metric_rx_num_sdu_bytes, uint32_t, ""); @@ -98,6 +114,17 @@ void rlc_metrics_consumer_json::handle_metric(const app_services::metrics_set& m tx_output.write(drb.tx.tx_high.num_dropped_sdus); tx_output.write(drb.tx.tx_high.num_discarded_sdus); tx_output.write(drb.tx.tx_high.num_discarded_sdus); + tx_output.write(drb.tx.tx_low.sum_sdu_latency_us); + tx_output.write(drb.tx.tx_low.sum_pdu_latency_ns); + tx_output.write(drb.tx.tx_low.max_pdu_latency_ns); + unsigned bin_idx = 0; + for (unsigned bin_count : drb.tx.tx_low.pdu_latency_hist_ns) { + tx_output.get().emplace_back(); + auto& elem = tx_output.get().back(); + elem.write(bin_idx * rlc_tx_metrics_lower::nof_usec_per_bin); + elem.write(bin_count); + bin_idx++; + } // RX metrics auto& rx_output = output.get(); diff --git a/lib/support/timers.cpp b/lib/support/timers.cpp index fbee9cbb00..a355f117b5 100644 --- a/lib/support/timers.cpp +++ b/lib/support/timers.cpp @@ -73,8 +73,9 @@ timer_manager::timer_manager(size_t capacity) : logger(srslog::fetch_basic_logge for (auto i = timer_list.rbegin(), e = timer_list.rend(); i != e; ++i) { free_list.emplace_back(i->frontend.get()); } - pending_cmds.reserve(16384); - cmds_to_process.reserve(16384); + const uint16_t cmds_capacity = 16384; + pending_cmds.reserve(cmds_capacity); + cmds_to_process.reserve(cmds_capacity); } void timer_manager::tick() diff --git a/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp index 685c14f7f4..58e1537a9e 100644 --- a/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp +++ b/tests/benchmarks/rlc/rlc_am_tx_benchmark.cpp @@ -174,7 +174,8 @@ void benchmark_tx_pdu(const bench_params& params) uint64_t bm_duration_ns = bm->get_total_meas_time_ns(); std::chrono::nanoseconds bm_duration(bm_duration_ns); rlc_tx_metrics tx_metrics = rlc_tx->get_metrics(); - fmt::print("RLC TX metrics: {}\n", + fmt::print("\nRLC TX metrics:\n"); + fmt::print(" - {}\n", format_rlc_tx_metrics(std::chrono::duration_cast(bm_duration), tx_metrics)); } From e482df378019dd9e5b7a20afef9f9306aa599f8e Mon Sep 17 00:00:00 2001 From: qarlosalberto Date: Mon, 23 Sep 2024 19:11:40 +0200 Subject: [PATCH 114/174] ci: add warning to table --- tests/e2e/tests/steps/stub.py | 59 +++++++++--------- tests/e2e/tests/viavi.py | 36 ++++++++--- tests/e2e/tests/viavi/test_declaration.yml | 62 +++++-------------- .../tests/viavi/test_declaration_debug.yml | 6 +- .../tests/viavi/test_declaration_schema.json | 6 +- 5 files changed, 80 insertions(+), 89 deletions(-) diff --git a/tests/e2e/tests/steps/stub.py b/tests/e2e/tests/steps/stub.py index 2279906594..94439a9eb9 100644 --- a/tests/e2e/tests/steps/stub.py +++ b/tests/e2e/tests/steps/stub.py @@ -587,29 +587,29 @@ def stop( # Stop error_msg_array = [] for index, ue_stub in enumerate(ue_array): - error_msg_array.append( - _stop_stub( - ue_stub, - f"UE_{index+1}", - retina_data, - ue_stop_timeout, - log_search, - warning_as_errors, - ) + error_message, _ = _stop_stub( + ue_stub, + f"UE_{index+1}", + retina_data, + ue_stop_timeout, + log_search, + warning_as_errors, ) + error_msg_array.append(error_message) + if gnb is not None: - error_msg_array.append(_stop_stub(gnb, "GNB", retina_data, gnb_stop_timeout, log_search, warning_as_errors)) + error_message, _ = _stop_stub(gnb, "GNB", retina_data, gnb_stop_timeout, log_search, warning_as_errors) + error_msg_array.append(error_message) if fivegc is not None: - error_msg_array.append( - _stop_stub( - fivegc, - "5GC", - retina_data, - fivegc_stop_timeout, - log_search, - warning_as_errors, - ) + error_message, _ = _stop_stub( + fivegc, + "5GC", + retina_data, + fivegc_stop_timeout, + log_search, + warning_as_errors, ) + error_msg_array.append(error_message) # Fail if stop errors error_msg_array = list(filter(bool, error_msg_array)) @@ -649,16 +649,15 @@ def ue_stop( """ error_msg_array = [] for index, ue_stub in enumerate(ue_array): - error_msg_array.append( - _stop_stub( - ue_stub, - f"UE_{index+1}", - retina_data, - ue_stop_timeout, - log_search, - warning_as_errors, - ) + error_message, _ = _stop_stub( + ue_stub, + f"UE_{index+1}", + retina_data, + ue_stop_timeout, + log_search, + warning_as_errors, ) + error_msg_array.append(error_message) error_msg_array = list(filter(bool, error_msg_array)) if error_msg_array: pytest.fail( @@ -674,7 +673,7 @@ def _stop_stub( timeout: int = 0, log_search: bool = True, warning_as_errors: bool = True, -) -> str: +) -> Tuple[str, int]: """ Stop a stub in the defined timeout (0=auto). It uses retina_data to save artifacts in case of failure @@ -707,7 +706,7 @@ def _stop_stub( else: logging.info("%s has stopped", name) - return error_msg + return error_msg, stop_info.warning_count def _get_metrics_msg(stub: RanStub, name: str, fail_if_kos: bool = False) -> str: diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index 00f3a6c237..56e34a6513 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -32,7 +32,7 @@ from .steps.configuration import configure_metric_server_for_gnb from .steps.kpis import get_kpis, KPIs -from .steps.stub import GNB_STARTUP_TIMEOUT, handle_start_error, stop +from .steps.stub import _stop_stub, GNB_STARTUP_TIMEOUT, handle_start_error, stop _OMIT_VIAVI_FAILURE_LIST = ["authentication"] _FLAKY_ERROR_LIST = ["Error creating the pod", "Viavi API call timed out"] @@ -56,7 +56,7 @@ class _ViaviConfiguration: # test/fail criteria expected_ul_bitrate: float = 0 expected_dl_bitrate: float = 0 - fail_if_kos: bool = True + expected_nof_kos: int = 0 warning_as_errors: bool = True @@ -95,7 +95,7 @@ def load_yaml_config(config_filename: str) -> List[_ViaviConfiguration]: enable_qos_viavi=test_declaration["enable_qos_viavi"], expected_dl_bitrate=test_declaration["expected_dl_bitrate"], expected_ul_bitrate=test_declaration["expected_ul_bitrate"], - fail_if_kos=test_declaration["fail_if_kos"], + expected_nof_kos=test_declaration["expected_nof_kos"], warning_as_errors=test_declaration["warning_as_errors"], ) ) @@ -383,6 +383,9 @@ def _test_viavi( if info.status is not CampaignStatusEnum.PASS: pytest.fail(f"Viavi Test Failed: {info.message}") # Final stop + _, gnb_warning_count = _stop_stub( + gnb, "GNB", retina_data, gnb_stop_timeout, log_search, test_declaration.warning_as_errors + ) stop( (), gnb, @@ -391,7 +394,7 @@ def _test_viavi( gnb_stop_timeout=gnb_stop_timeout, log_search=log_search, warning_as_errors=test_declaration.warning_as_errors, - fail_if_kos=test_declaration.fail_if_kos, + fail_if_kos=False, ) # This except and the finally should be inside the request, but the campaign_name makes it complicated @@ -407,7 +410,15 @@ def _test_viavi( logging.info("Folder with Viavi report: %s", report_folder) logging.info("Downloading Viavi report") viavi.download_directory(report_folder, Path(test_log_folder).joinpath("viavi")) - check_metrics_criteria(test_declaration, gnb, viavi, metrics_summary, test_declaration.fail_if_kos, capsys) + check_metrics_criteria( + test_configuration=test_declaration, + gnb=gnb, + viavi=viavi, + metrics_summary=metrics_summary, + capsys=capsys, + gnb_warning_count=gnb_warning_count, + warning_as_errors=test_declaration.warning_as_errors, + ) except HTTPError: logging.error("Viavi Reports could not be downloaded") @@ -420,8 +431,9 @@ def check_metrics_criteria( gnb: GNBStub, viavi: Viavi, metrics_summary: Optional[MetricsSummary], - fail_if_kos: bool, capsys: pytest.CaptureFixture[str], + gnb_warning_count: int, + warning_as_errors: bool, ): """ Check pass/fail criteria @@ -452,11 +464,19 @@ def check_metrics_criteria( ) ) - criteria_nof_ko_aggregate = check_criteria(kpis.nof_ko_aggregate, 0, operator.eq) or not fail_if_kos + criteria_nof_ko_aggregate = check_criteria(kpis.nof_ko_aggregate, test_configuration.expected_nof_kos, operator.lt) criteria_result.append( - _ViaviResult("Number of KOs and/or retrxs", 0, kpis.nof_ko_aggregate, criteria_nof_ko_aggregate) + _ViaviResult( + "Number of KOs and/or retrxs", + test_configuration.expected_nof_kos, + kpis.nof_ko_aggregate, + criteria_nof_ko_aggregate, + ) ) + criteria_nof_warnings = check_criteria(gnb_warning_count, 0, operator.eq) and warning_as_errors + criteria_result.append(_ViaviResult("Number of warnings", 0, gnb_warning_count, criteria_nof_warnings)) + # Check procedure table viavi_failure_manager.print_failures(_OMIT_VIAVI_FAILURE_LIST) criteria_procedure_table = viavi_failure_manager.get_number_of_failures(_OMIT_VIAVI_FAILURE_LIST) == 0 diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index cd67403d03..08dc6ba55f 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -16,11 +16,11 @@ # enable_qos_viavi: enable QoS in GNB configuration for Viavi # expected_dl_bitrate: pass/fail criteria, expected downlink bitrate in bps # expected_ul_bitrate: pass/fail criteria, expected uplink bitrate in bps -# fail_if_kos: fail if KPIs are out of spec +# expected_nof_kos: expected_nof_kos # warning_as_errors: treat warnings as errors campaign_filename: &campaign_filename "C:\\ci\\CI 4x4 ORAN-FH-complete.xml" -gnb_extra_commands: &gnb_extra_commands "ru_ofh --ta4_max 700 --ta4_min 10" +gnb_extra_commands: &gnb_extra_commands "ru_ofh --ta4_max 700 --ta4_min 10 metrics --rlc_report_period=1000" test_timeout: &test_timeout 1800 # 30 * 60 tests: @@ -35,7 +35,7 @@ tests: # test/fail criteria expected_dl_bitrate: 1.2e+9 expected_ul_bitrate: 80.0e+6 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: true - campaign_filename: *campaign_filename @@ -49,7 +49,7 @@ tests: # test/fail criteria expected_dl_bitrate: 1.2e+9 expected_ul_bitrate: 80.0e+6 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: true - campaign_filename: *campaign_filename @@ -63,7 +63,7 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: false + expected_nof_kos: 9999999999999 warning_as_errors: true - campaign_filename: *campaign_filename @@ -77,7 +77,7 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: false + expected_nof_kos: 9999999999999 warning_as_errors: true - campaign_filename: *campaign_filename @@ -91,7 +91,7 @@ tests: # test/fail criteria expected_dl_bitrate: 1.0e+9 expected_ul_bitrate: 1.0e+3 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: true - campaign_filename: *campaign_filename @@ -105,7 +105,7 @@ tests: # test/fail criteria expected_dl_bitrate: 1.0e+9 expected_ul_bitrate: 1.0e+3 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: true - campaign_filename: *campaign_filename @@ -119,7 +119,7 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: false + expected_nof_kos: 9999999999999 warning_as_errors: true - campaign_filename: *campaign_filename @@ -133,13 +133,13 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: false + expected_nof_kos: 9999999999999 warning_as_errors: false - campaign_filename: *campaign_filename test_name: "32UE ideal UDP attach-detach with traffic" test_timeout: *test_timeout - gnb_extra_commands: "log --ngap_level=debug --rrc_level=debug" + gnb_extra_commands: "log --ngap_level=debug metrics --rlc_report_period=1000" id: "32UE ideal UDP attach-detach with traffic" max_pdschs_per_slot: 1 max_puschs_per_slot: 4 @@ -147,23 +147,9 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: true - # - campaign_filename: *campaign_filename - # test_name: "32UE fading UDP attach-detach with traffic" - # test_timeout: *test_timeout - # gnb_extra_commands: *gnb_extra_commands - # id: "32UE fading UDP attach-detach with traffic" - # max_pdschs_per_slot: 1 - # max_puschs_per_slot: 4 - # enable_qos_viavi: false - # # test/fail criteria - # expected_dl_bitrate: 14.0e+3 - # expected_ul_bitrate: 1.0e+3 - # fail_if_kos: false - # warning_as_errors: false - - campaign_filename: *campaign_filename test_name: "1UE birth-death UDP bidirectional" test_timeout: *test_timeout @@ -175,23 +161,9 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: false + expected_nof_kos: 9999999999999 warning_as_errors: true - # - campaign_filename: *campaign_filename - # test_name: "32UE birth-death UDP bidirectional" - # test_timeout: *test_timeout - # gnb_extra_commands: *gnb_extra_commands - # id: "32UE birth-death UDP bidirectional" - # max_pdschs_per_slot: 1 - # max_puschs_per_slot: 4 - # enable_qos_viavi: false - # # test/fail criteria - # expected_dl_bitrate: 14.0e+3 - # expected_ul_bitrate: 1.0e+3 - # fail_if_kos: true - # warning_as_errors: true - - campaign_filename: *campaign_filename test_name: "32UE ideal ping" test_timeout: *test_timeout @@ -203,7 +175,7 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: true - campaign_filename: *campaign_filename @@ -217,7 +189,7 @@ tests: # test/fail criteria expected_dl_bitrate: 14.0e+3 expected_ul_bitrate: 1.0e+3 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: true - campaign_filename: *campaign_filename @@ -231,7 +203,7 @@ tests: # test/fail criteria expected_dl_bitrate: 1.2e+9 expected_ul_bitrate: 80.0e+6 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: false - campaign_filename: *campaign_filename @@ -245,5 +217,5 @@ tests: # test/fail criteria expected_dl_bitrate: 1.2e+9 expected_ul_bitrate: 80.0e+6 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: false diff --git a/tests/e2e/tests/viavi/test_declaration_debug.yml b/tests/e2e/tests/viavi/test_declaration_debug.yml index e201b67508..1f03e5b1aa 100644 --- a/tests/e2e/tests/viavi/test_declaration_debug.yml +++ b/tests/e2e/tests/viavi/test_declaration_debug.yml @@ -16,11 +16,11 @@ # enable_qos_viavi: enable QoS in GNB configuration for Viavi # expected_dl_bitrate: pass/fail criteria, expected downlink bitrate in bps # expected_ul_bitrate: pass/fail criteria, expected uplink bitrate in bps -# fail_if_kos: fail if KPIs are out of spec +# expected_nof_kos: expected_nof_kos # warning_as_errors: treat warnings as errors campaign_filename: &campaign_filename "C:\\ci\\CI 4x4 ORAN-FH-complete.xml" -gnb_extra_commands: &gnb_extra_commands "" +gnb_extra_commands: &gnb_extra_commands "metrics --rlc_report_period=1000" tests: - campaign_filename: *campaign_filename @@ -34,5 +34,5 @@ tests: # test/fail criteria expected_dl_bitrate: 1.2e+9 expected_ul_bitrate: 80.0e+6 - fail_if_kos: true + expected_nof_kos: 3 warning_as_errors: false diff --git a/tests/e2e/tests/viavi/test_declaration_schema.json b/tests/e2e/tests/viavi/test_declaration_schema.json index 1588e090be..392fb7237f 100644 --- a/tests/e2e/tests/viavi/test_declaration_schema.json +++ b/tests/e2e/tests/viavi/test_declaration_schema.json @@ -37,8 +37,8 @@ "expected_ul_bitrate": { "type": "integer" }, - "fail_if_kos": { - "type": "boolean" + "expected_nof_kos": { + "type": "integer" }, "warning_as_errors": { "type": "boolean" @@ -55,7 +55,7 @@ "enable_qos_viavi", "expected_dl_bitrate", "expected_ul_bitrate", - "fail_if_kos", + "expected_nof_kos", "warning_as_errors" ], "additionalProperties": false From edc2566c1cf0a35e51c2df024be255bd92474430 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Mon, 23 Sep 2024 16:56:01 +0200 Subject: [PATCH 115/174] metrics: added PUCCH SINR and TA metrics to json consumer. Renamed property stdout_metrics_period to sched_report_period --- apps/units/flexible_du/du_high/du_high_config.h | 8 +++++--- .../flexible_du/du_high/du_high_config_cli11_schema.cpp | 4 ++-- .../flexible_du/du_high/du_high_config_translators.cpp | 2 +- .../flexible_du/du_high/du_high_config_yaml_writer.cpp | 8 ++++---- .../metrics/du_high_scheduler_cell_metrics_consumers.cpp | 8 ++++++++ 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/apps/units/flexible_du/du_high/du_high_config.h b/apps/units/flexible_du/du_high/du_high_config.h index 27d462620c..805b06f87a 100644 --- a/apps/units/flexible_du/du_high/du_high_config.h +++ b/apps/units/flexible_du/du_high/du_high_config.h @@ -639,11 +639,13 @@ struct du_high_unit_cell_config { /// Metrics report configuration. struct du_high_unit_metrics_config { struct rlc_metrics { - unsigned report_period = 0; // RLC report period in ms + /// RLC report period in ms. + unsigned report_period = 0; bool json_enabled = false; } rlc; - bool enable_json_metrics = false; - unsigned stdout_metrics_period = 1000; // Statistics report period in milliseconds + bool enable_json_metrics = false; + /// Scheduler report period in milliseconds. + unsigned sched_report_period = 1000; bool autostart_stdout_metrics = false; }; diff --git a/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp b/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp index d9e5a213ae..3a4624741d 100644 --- a/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_cli11_schema.cpp @@ -1435,8 +1435,8 @@ static void configure_cli11_metrics_args(CLI::App& app, du_high_unit_metrics_con ->capture_default_str(); add_option(app, - "--stdout_metrics_period", - metrics_params.stdout_metrics_period, + "--sched_report_period", + metrics_params.sched_report_period, "DU statistics report period in milliseconds. This metrics sets the console output period.") ->capture_default_str(); } diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index c0bfa30ed8..b3653875c7 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -888,7 +888,7 @@ scheduler_expert_config srsran::generate_scheduler_expert_config(const du_high_u // Logging and tracing. out_cfg.log_broadcast_messages = config.loggers.broadcast_enabled; - out_cfg.metrics_report_period = std::chrono::milliseconds{config.metrics.stdout_metrics_period}; + out_cfg.metrics_report_period = std::chrono::milliseconds{config.metrics.sched_report_period}; const error_type error = is_scheduler_expert_config_valid(out_cfg); if (!error) { diff --git a/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp b/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp index 20a5f3ff00..afd2ca7991 100644 --- a/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_yaml_writer.cpp @@ -16,10 +16,10 @@ using namespace srsran; static void fill_du_high_metrics_section(YAML::Node node, const du_high_unit_metrics_config& config) { - node["rlc_report_period"] = config.rlc.report_period; - node["rlc_json_enable"] = config.rlc.json_enabled; - node["enable_json_metrics"] = config.enable_json_metrics; - node["stdout_metrics_period"] = config.stdout_metrics_period; + node["rlc_report_period"] = config.rlc.report_period; + node["rlc_json_enable"] = config.rlc.json_enabled; + node["enable_json_metrics"] = config.enable_json_metrics; + node["sched_report_period"] = config.sched_report_period; } static void fill_du_high_pcap_section(YAML::Node node, const du_high_unit_pcap_config& config) diff --git a/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp b/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp index b84cd2237f..9ddda9e8bf 100644 --- a/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp +++ b/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp @@ -32,6 +32,8 @@ DECLARE_METRIC("dl_nof_ok", metric_dl_nof_ok, unsigned, ""); DECLARE_METRIC("dl_nof_nok", metric_dl_nof_nok, unsigned, ""); DECLARE_METRIC("dl_bs", metric_dl_bs, unsigned, ""); DECLARE_METRIC("pusch_snr_db", metric_pusch_snr_db, float, ""); +DECLARE_METRIC("pucch_snr_db", metric_pucch_snr_db, float, ""); +DECLARE_METRIC("ta_ns", metric_ta_ns, std::string, ""); DECLARE_METRIC("ul_mcs", metric_ul_mcs, uint8_t, ""); DECLARE_METRIC("ul_brate", metric_ul_brate, double, ""); DECLARE_METRIC("ul_nof_ok", metric_ul_nof_ok, unsigned, ""); @@ -49,6 +51,8 @@ DECLARE_METRIC_SET("ue_container", metric_dl_nof_nok, metric_dl_bs, metric_pusch_snr_db, + metric_pucch_snr_db, + metric_ta_ns, metric_ul_mcs, metric_ul_brate, metric_ul_nof_ok, @@ -216,6 +220,10 @@ void scheduler_cell_metrics_consumer_json::handle_metric(const app_services::met if (!std::isnan(ue.pusch_snr_db) && !iszero(ue.pusch_snr_db)) { output.write(std::clamp(ue.pusch_snr_db, -99.9f, 99.9f)); } + if (!std::isnan(ue.pucch_snr_db) && !iszero(ue.pucch_snr_db)) { + output.write(std::clamp(ue.pucch_snr_db, -99.9f, 99.9f)); + } + output.write(ue.last_ta ? std::to_string(ue.last_ta->to_seconds() * 1e9) : "n/a"); output.write(ue.ul_mcs.to_uint()); output.write(ue.ul_brate_kbps * 1e3); output.write(ue.ul_nof_ok); From 302a45f91aa5b3d36c77d0d48e2dbd8cd3dc6207 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 18 Sep 2024 14:43:03 +0200 Subject: [PATCH 116/174] cu_cp: add func pointer for mocn support --- apps/gnb/gnb.cpp | 19 +++++++ apps/units/cu_cp/cu_cp_unit_config.h | 4 ++ include/srsran/cu_cp/cu_cp_configuration.h | 12 +++++ .../amf_connection_manager.cpp | 52 +++++++++++++------ .../cu_cp_controller/amf_connection_manager.h | 4 ++ .../cu_cp_controller/cu_cp_controller.cpp | 4 +- lib/cu_cp/cu_cp_controller/cu_cp_controller.h | 2 + lib/cu_cp/cu_cp_impl.cpp | 10 +++- lib/cu_cp/cu_cp_impl.h | 2 + .../routines/amf_connection_setup_routine.h | 1 - 10 files changed, 92 insertions(+), 18 deletions(-) diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 875f749134..1ae40077a0 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -377,6 +377,8 @@ int main(int argc, char** argv) // Load CU-CP plugins if enabled std::optional ng_handover_plugin = cu_cp_config.load_plugins ? dynlink_manager::create("libsrsran_plugin_ng_handover.so", gnb_logger) : std::nullopt; + std::optional mocn_plugin = + cu_cp_config.load_plugins ? dynlink_manager::create("libsrsran_plugin_mocn.so", gnb_logger) : std::nullopt; if (cu_cp_config.load_plugins) { if (not ng_handover_plugin) { gnb_logger.error("Could not open NG Handover plugin"); @@ -388,6 +390,23 @@ int main(int argc, char** argv) return -1; } cu_cp_config.start_ng_ho_func = ng_ho_func.value(); + + if (not mocn_plugin) { + gnb_logger.error("Could not open MOCN plugin"); + return -1; + } + expected connect_amfs = mocn_plugin->load_symbol("connect_amfs_func"); + if (not connect_amfs) { + gnb_logger.error("Could not open MOCN function pointer"); + return -1; + } + cu_cp_config.connect_amfs_func_ptr = connect_amfs.value(); + expected disconnect_amfs = mocn_plugin->load_symbol("disconnect_amfs_func"); + if (not disconnect_amfs) { + gnb_logger.error("Could not open MOCN function pointer"); + return -1; + } + cu_cp_config.disconnect_amfs_func_ptr = disconnect_amfs.value(); } // Create N2 Client Gateways. diff --git a/apps/units/cu_cp/cu_cp_unit_config.h b/apps/units/cu_cp/cu_cp_unit_config.h index eae8854edb..7eb604af86 100644 --- a/apps/units/cu_cp/cu_cp_unit_config.h +++ b/apps/units/cu_cp/cu_cp_unit_config.h @@ -266,6 +266,10 @@ struct cu_cp_unit_config { bool load_plugins = false; /// Function pointer to start NG handover from plugin void* start_ng_ho_func; + /// Function pointer to connect to AMFs from plugin + void* connect_amfs_func_ptr; + /// Function pointer to disconnect from AMFs from plugin + void* disconnect_amfs_func_ptr; /// PDU session setup timeout in seconds (must be larger than T310). unsigned pdu_session_setup_timeout = 3; /// Loggers configuration. diff --git a/include/srsran/cu_cp/cu_cp_configuration.h b/include/srsran/cu_cp/cu_cp_configuration.h index fe7abbb773..2f69b2ece7 100644 --- a/include/srsran/cu_cp/cu_cp_configuration.h +++ b/include/srsran/cu_cp/cu_cp_configuration.h @@ -15,12 +15,20 @@ #include "srsran/cu_cp/ue_configuration.h" #include "srsran/f1ap/cu_cp/f1ap_configuration.h" #include "srsran/rrc/rrc_ue_config.h" +#include "srsran/support/async/async_task.h" #include "srsran/support/executors/task_executor.h" namespace srsran { namespace srs_cu_cp { class n2_connection_client; +class ngap_repository; + +using connect_amfs_func = async_task (*)(ngap_repository& ngap_db, + std::unordered_map>& amfs_connected); + +using disconnect_amfs_func = async_task (*)(ngap_repository& ngap_db, + std::unordered_map>& amfs_connected); struct plmn_item { plmn_identity plmn_id; @@ -99,6 +107,10 @@ struct cu_cp_configuration { bool load_plugins; /// Loaded function pointer to trigger NG Handover void* start_ng_ho_func = nullptr; + /// Loaded function pointer to connect to AMFs + connect_amfs_func connect_amfs = nullptr; + /// Loaded function pointer to disconnect from AMFs + disconnect_amfs_func disconnect_amfs = nullptr; }; /// NG-RAN node parameters. diff --git a/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp b/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp index 35192f4058..32c99fb5b5 100644 --- a/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp +++ b/lib/cu_cp/cu_cp_controller/amf_connection_manager.cpp @@ -20,10 +20,24 @@ using namespace srsran; using namespace srs_cu_cp; +// Function prototype for connecting to AMFs from plugin +async_task +connect_amfs(ngap_repository& ngap_db, + std::unordered_map>& amfs_connected) asm("connect_amfs_func"); + +// Function prototype for disconnecting from AMFs from plugin +async_task +disconnect_amfs(ngap_repository& ngap_db, + std::unordered_map>& amfs_connected) asm("disconnect_amfs_func"); + amf_connection_manager::amf_connection_manager(ngap_repository& ngaps_, + connect_amfs_func connect_amfs_, + disconnect_amfs_func disconnect_amfs_, task_executor& cu_cp_exec_, common_task_scheduler& common_task_sched_) : ngaps(ngaps_), + connect_amfs(connect_amfs_), + disconnect_amfs(disconnect_amfs_), cu_cp_exec(cu_cp_exec_), common_task_sched(common_task_sched_), logger(srslog::fetch_basic_logger("CU-CP")) @@ -33,21 +47,25 @@ amf_connection_manager::amf_connection_manager(ngap_repository& ngaps_, void amf_connection_manager::connect_to_amf(std::promise* completion_signal) { // Schedules setup routine to be executed in sequence with other CU-CP procedures. - common_task_sched.schedule_async_task(launch_async([this, p = completion_signal]( - coro_context>& ctx) mutable { - CORO_BEGIN(ctx); - - // Launch procedure to initiate AMF connection. - amfs_connected.emplace(ngaps.get_ngaps().begin()->first, false); - CORO_AWAIT_VALUE(bool success, launch_async(ngaps, amfs_connected.begin()->second)); - - // Signal through the promise the result of the connection setup. - if (p != nullptr) { - p->set_value(success); - } - - CORO_RETURN(); - })); + common_task_sched.schedule_async_task( + launch_async([this, success = false, p = completion_signal](coro_context>& ctx) mutable { + CORO_BEGIN(ctx); + + if (connect_amfs != nullptr) { + CORO_AWAIT_VALUE(success, (*connect_amfs)(ngaps, amfs_connected)); + } else { + // Launch procedure to initiate AMF connection. + amfs_connected.emplace(ngaps.get_ngaps().begin()->first, false); + CORO_AWAIT_VALUE(success, launch_async(ngaps, amfs_connected.begin()->second)); + } + + // Signal through the promise the result of the connection setup. + if (p != nullptr) { + p->set_value(success); + } + + CORO_RETURN(); + })); } async_task amf_connection_manager::disconnect_amf() @@ -60,6 +78,10 @@ async_task amf_connection_manager::disconnect_amf() }); } + if (disconnect_amfs != nullptr) { + return (*disconnect_amfs)(ngaps, amfs_connected); + } + return launch_async(ngaps.get_ngaps().begin()->second, amfs_connected.begin()->second); } diff --git a/lib/cu_cp/cu_cp_controller/amf_connection_manager.h b/lib/cu_cp/cu_cp_controller/amf_connection_manager.h index 5d0058cddd..b8a85509b7 100644 --- a/lib/cu_cp/cu_cp_controller/amf_connection_manager.h +++ b/lib/cu_cp/cu_cp_controller/amf_connection_manager.h @@ -26,6 +26,8 @@ class amf_connection_manager { public: amf_connection_manager(ngap_repository& ngaps_, + connect_amfs_func connect_amfs_, + disconnect_amfs_func disconnect_amfs_, task_executor& cu_cp_exec_, common_task_scheduler& common_task_sched_); @@ -48,6 +50,8 @@ class amf_connection_manager amf_index_t plmn_to_amf_index(plmn_identity plmn) const; ngap_repository& ngaps; + connect_amfs_func connect_amfs; + disconnect_amfs_func disconnect_amfs; task_executor& cu_cp_exec; common_task_scheduler& common_task_sched; srslog::basic_logger& logger; diff --git a/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp b/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp index 705e6951cc..20224c2ad3 100644 --- a/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp +++ b/lib/cu_cp/cu_cp_controller/cu_cp_controller.cpp @@ -21,11 +21,13 @@ cu_cp_controller::cu_cp_controller(const cu_cp_configuration& config_, ngap_repository& ngaps_, cu_up_processor_repository& cu_ups_, du_processor_repository& dus_, + connect_amfs_func connect_amfs_, + disconnect_amfs_func disconnect_amfs_, task_executor& ctrl_exec_) : cfg(config_), ctrl_exec(ctrl_exec_), logger(srslog::fetch_basic_logger("CU-CP")), - amf_mng(ngaps_, ctrl_exec_, common_task_sched_), + amf_mng(ngaps_, connect_amfs_, disconnect_amfs_, ctrl_exec_, common_task_sched_), du_mng(cfg.admission.max_nof_dus, dus_, ctrl_exec, common_task_sched_), cu_up_mng(cfg.admission.max_nof_cu_ups, cu_ups_, ctrl_exec, common_task_sched_) { diff --git a/lib/cu_cp/cu_cp_controller/cu_cp_controller.h b/lib/cu_cp/cu_cp_controller/cu_cp_controller.h index 92a99eeaba..917973b589 100644 --- a/lib/cu_cp/cu_cp_controller/cu_cp_controller.h +++ b/lib/cu_cp/cu_cp_controller/cu_cp_controller.h @@ -40,6 +40,8 @@ class cu_cp_controller : public cu_cp_ue_admission_controller ngap_repository& ngaps_, cu_up_processor_repository& cu_ups_, du_processor_repository& dus_, + connect_amfs_func connect_amfs_, + disconnect_amfs_func disconnect_amfs_, task_executor& ctrl_exec); void stop(); diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 817ee89608..a1c3ec1282 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -77,11 +77,19 @@ cu_cp_impl::cu_cp_impl(const cu_cp_configuration& config_) : start_ho_prep_func = reinterpret_cast(cfg.plugin.start_ng_ho_func); } + if (cfg.plugin.connect_amfs != nullptr) { + connect_amfs = reinterpret_cast(cfg.plugin.connect_amfs); + } + + if (cfg.plugin.disconnect_amfs != nullptr) { + disconnect_amfs = reinterpret_cast(cfg.plugin.disconnect_amfs); + } + ngap_db = std::make_unique(ngap_repository_config{ cfg, get_cu_cp_ngap_handler(), paging_handler, start_ho_prep_func, srslog::fetch_basic_logger("CU-CP")}); controller = std::make_unique( - cfg, common_task_sched, *ngap_db, cu_up_db, du_db, *cfg.services.cu_cp_executor); + cfg, common_task_sched, *ngap_db, cu_up_db, du_db, connect_amfs, disconnect_amfs, *cfg.services.cu_cp_executor); conn_notifier.connect_node_connection_handler(*controller); mobility_mng = create_mobility_manager( diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index 08f5eb8d2b..1161abcef5 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -206,6 +206,8 @@ class cu_cp_impl final : public cu_cp, // Plug-ins start_ngap_handover_preparation_procedure_func start_ho_prep_func = nullptr; + connect_amfs_func connect_amfs = nullptr; + disconnect_amfs_func disconnect_amfs = nullptr; }; } // namespace srs_cu_cp diff --git a/lib/cu_cp/routines/amf_connection_setup_routine.h b/lib/cu_cp/routines/amf_connection_setup_routine.h index 78b511ad63..4d97a5afcf 100644 --- a/lib/cu_cp/routines/amf_connection_setup_routine.h +++ b/lib/cu_cp/routines/amf_connection_setup_routine.h @@ -10,7 +10,6 @@ #pragma once -#include "../cu_cp_impl_interface.h" #include "../ngap_repository.h" #include "srsran/cu_cp/cu_cp_configuration.h" #include "srsran/ngap/ngap.h" From 957a31276f895ecc9bbe204db7536f200d3680ac Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 18 Sep 2024 14:43:41 +0200 Subject: [PATCH 117/174] cu_cp: add handling of func pointer to unit tests --- .../cu_cp/cu_cp_test_environment.cpp | 6 ++++++ .../unittests/cu_cp/cu_cp_test_environment.h | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.cpp b/tests/unittests/cu_cp/cu_cp_test_environment.cpp index 9beb77478f..67d14c357a 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.cpp +++ b/tests/unittests/cu_cp/cu_cp_test_environment.cpp @@ -92,6 +92,12 @@ cu_cp_test_environment::cu_cp_test_environment(cu_cp_test_env_params params_) : cu_cp_cfg.f1ap.json_log_enabled = true; + // > Plugin config + cu_cp_cfg.plugin.load_plugins = params.load_plugins; + cu_cp_cfg.plugin.start_ng_ho_func = params.start_ng_ho_func; + cu_cp_cfg.plugin.connect_amfs = params.connect_amfs; + cu_cp_cfg.plugin.disconnect_amfs = params.disconnect_amfs; + // > Mobility config cu_cp_cfg.mobility.mobility_manager_config.trigger_handover_from_measurements = true; { diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.h b/tests/unittests/cu_cp/cu_cp_test_environment.h index f7bcd5529f..28145b68d1 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.h +++ b/tests/unittests/cu_cp/cu_cp_test_environment.h @@ -10,6 +10,7 @@ #pragma once +#include "../../../lib/cu_cp/cu_cp_controller/amf_connection_manager.h" #include "../e1ap/common/e1ap_cu_cp_test_messages.h" #include "test_doubles/mock_amf.h" #include "test_doubles/mock_cu_up.h" @@ -35,8 +36,18 @@ struct cu_cp_test_env_params { unsigned max_nof_dus_ = 8, unsigned max_nof_ues_ = 8192, const std::vector>& amf_config_ = - {{supported_tracking_area{7, {{plmn_identity::test_value(), {{1}}}}}}}) : - max_nof_cu_ups(max_nof_cu_ups_), max_nof_dus(max_nof_dus_), max_nof_ues(max_nof_ues_) + {{supported_tracking_area{7, {{plmn_identity::test_value(), {{1}}}}}}}, + bool load_plugins_ = false, + void* start_ng_ho_func_ = nullptr, + connect_amfs_func connect_amfs_ = nullptr, + disconnect_amfs_func disconnect_amfs_ = nullptr) : + max_nof_cu_ups(max_nof_cu_ups_), + max_nof_dus(max_nof_dus_), + max_nof_ues(max_nof_ues_), + load_plugins(load_plugins_), + start_ng_ho_func(start_ng_ho_func_), + connect_amfs(connect_amfs_), + disconnect_amfs(disconnect_amfs_) { uint16_t amf_idx = 0; for (const auto& supported_tas : amf_config_) { @@ -47,6 +58,10 @@ struct cu_cp_test_env_params { unsigned max_nof_cu_ups; unsigned max_nof_dus; unsigned max_nof_ues; + bool load_plugins; + void* start_ng_ho_func; + connect_amfs_func connect_amfs; + disconnect_amfs_func disconnect_amfs; std::map amf_configs; }; From a106293be128c6f02a9db4abeeab0ed3c813fada Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 18 Sep 2024 14:44:00 +0200 Subject: [PATCH 118/174] cu_cp: export libraries for plugins --- lib/asn1/CMakeLists.txt | 8 ++++++++ lib/asn1/rrc_nr/CMakeLists.txt | 2 ++ lib/cu_cp/CMakeLists.txt | 2 ++ lib/cu_cp/cell_meas_manager/CMakeLists.txt | 4 +++- lib/cu_cp/mobility_manager/CMakeLists.txt | 4 +++- lib/cu_cp/ue_security_manager/CMakeLists.txt | 2 ++ lib/cu_cp/up_resource_manager/CMakeLists.txt | 4 +++- lib/e1ap/common/CMakeLists.txt | 2 ++ lib/e1ap/cu_cp/CMakeLists.txt | 2 ++ lib/f1ap/CMakeLists.txt | 2 ++ lib/f1ap/cu_cp/CMakeLists.txt | 2 ++ lib/ngap/CMakeLists.txt | 2 ++ lib/pdcp/CMakeLists.txt | 2 ++ lib/rrc/CMakeLists.txt | 4 +++- lib/security/CMakeLists.txt | 2 ++ tests/test_doubles/e1ap/CMakeLists.txt | 2 ++ tests/test_doubles/f1ap/CMakeLists.txt | 2 ++ tests/test_doubles/ngap/CMakeLists.txt | 2 ++ tests/test_doubles/pdcp/CMakeLists.txt | 2 ++ tests/test_doubles/rrc/CMakeLists.txt | 2 ++ tests/unittests/cu_cp/CMakeLists.txt | 2 ++ tests/unittests/e1ap/common/CMakeLists.txt | 2 ++ tests/unittests/f1ap/common/CMakeLists.txt | 2 ++ tests/unittests/ngap/CMakeLists.txt | 2 ++ 24 files changed, 58 insertions(+), 4 deletions(-) diff --git a/lib/asn1/CMakeLists.txt b/lib/asn1/CMakeLists.txt index de79c2127b..9992a5ce7c 100644 --- a/lib/asn1/CMakeLists.txt +++ b/lib/asn1/CMakeLists.txt @@ -11,6 +11,8 @@ add_library(asn1_utils STATIC asn1_utils.cpp) target_compile_options(asn1_utils PRIVATE -fno-exceptions) target_link_libraries(asn1_utils srslog srsran_support) +add_to_exported_libs(asn1_utils) + # RRC NR ASN1 add_subdirectory(rrc_nr) @@ -20,11 +22,15 @@ add_library(f1ap_asn1 STATIC f1ap/common.cpp f1ap/f1ap_ies.cpp f1ap/f1ap_pdu_ite target_compile_options(f1ap_asn1 PRIVATE -Os -fno-exceptions) target_link_libraries(f1ap_asn1 asn1_utils) +add_to_exported_libs(f1ap_asn1) + # E1AP ASN1 add_library(e1ap_asn1 STATIC e1ap/e1ap.cpp e1ap/e1ap_ies.cpp e1ap/e1ap_pdu_contents.cpp) target_compile_options(e1ap_asn1 PRIVATE -Os -fno-exceptions) target_link_libraries(e1ap_asn1 asn1_utils) +add_to_exported_libs(e1ap_asn1) + # E2AP ASN1 add_library(e2ap_asn1 STATIC e2ap/e2ap.cpp e2sm/e2sm_common_ies.cpp e2sm/e2sm_kpm_ies.cpp e2sm/e2sm_rc_ies.cpp) target_compile_options(e2ap_asn1 PRIVATE -Os -fno-exceptions) @@ -34,3 +40,5 @@ target_link_libraries(e2ap_asn1 asn1_utils) add_library(ngap_asn1 STATIC ngap/common.cpp ngap/ngap_ies.cpp ngap/ngap_pdu_contents.cpp ngap/ngap.cpp) target_compile_options(ngap_asn1 PRIVATE -Os -fno-exceptions) target_link_libraries(ngap_asn1 asn1_utils) + +add_to_exported_libs(ngap_asn1) \ No newline at end of file diff --git a/lib/asn1/rrc_nr/CMakeLists.txt b/lib/asn1/rrc_nr/CMakeLists.txt index e8f0ee9e01..efbbb2dd6b 100644 --- a/lib/asn1/rrc_nr/CMakeLists.txt +++ b/lib/asn1/rrc_nr/CMakeLists.txt @@ -37,3 +37,5 @@ add_library(rrc_nr_asn1 STATIC rrc_nr.cpp) target_compile_options(rrc_nr_asn1 PRIVATE -Os -fno-exceptions) target_link_libraries(rrc_nr_asn1 asn1_utils) + +add_to_exported_libs(rrc_nr_asn1) \ No newline at end of file diff --git a/lib/cu_cp/CMakeLists.txt b/lib/cu_cp/CMakeLists.txt index 80561f61dd..e7900ecb90 100644 --- a/lib/cu_cp/CMakeLists.txt +++ b/lib/cu_cp/CMakeLists.txt @@ -67,3 +67,5 @@ target_link_libraries(srsran_cu_cp srsran_security ${CMAKE_DL_LIBS} ) + +add_to_exported_libs(srsran_cu_cp) \ No newline at end of file diff --git a/lib/cu_cp/cell_meas_manager/CMakeLists.txt b/lib/cu_cp/cell_meas_manager/CMakeLists.txt index a056fed33f..d8b6ba891c 100644 --- a/lib/cu_cp/cell_meas_manager/CMakeLists.txt +++ b/lib/cu_cp/cell_meas_manager/CMakeLists.txt @@ -14,4 +14,6 @@ set(SOURCES add_library(srsran_cu_cp_cell_meas_manager STATIC ${SOURCES}) target_link_libraries(srsran_cu_cp_cell_meas_manager srsran_ran) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_to_exported_libs(srsran_cu_cp_cell_meas_manager) \ No newline at end of file diff --git a/lib/cu_cp/mobility_manager/CMakeLists.txt b/lib/cu_cp/mobility_manager/CMakeLists.txt index 7ace60ecef..a6f48b1e32 100644 --- a/lib/cu_cp/mobility_manager/CMakeLists.txt +++ b/lib/cu_cp/mobility_manager/CMakeLists.txt @@ -14,4 +14,6 @@ set(SOURCES add_library(srsran_cu_cp_mobility_manager STATIC ${SOURCES}) target_link_libraries(srsran_cu_cp_mobility_manager srsran_ran) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_to_exported_libs(srsran_cu_cp_mobility_manager) diff --git a/lib/cu_cp/ue_security_manager/CMakeLists.txt b/lib/cu_cp/ue_security_manager/CMakeLists.txt index e372d670fd..17edacdebe 100644 --- a/lib/cu_cp/ue_security_manager/CMakeLists.txt +++ b/lib/cu_cp/ue_security_manager/CMakeLists.txt @@ -13,3 +13,5 @@ set(SOURCES add_library(srsran_ue_security_manager STATIC ${SOURCES}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_to_exported_libs(srsran_ue_security_manager) diff --git a/lib/cu_cp/up_resource_manager/CMakeLists.txt b/lib/cu_cp/up_resource_manager/CMakeLists.txt index 2a0fb4404d..77e75a6a29 100644 --- a/lib/cu_cp/up_resource_manager/CMakeLists.txt +++ b/lib/cu_cp/up_resource_manager/CMakeLists.txt @@ -13,4 +13,6 @@ set(SOURCES add_library(srsran_up_resource_manager STATIC ${SOURCES}) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_to_exported_libs(srsran_up_resource_manager) diff --git a/lib/e1ap/common/CMakeLists.txt b/lib/e1ap/common/CMakeLists.txt index bf66204595..820e58f589 100644 --- a/lib/e1ap/common/CMakeLists.txt +++ b/lib/e1ap/common/CMakeLists.txt @@ -8,3 +8,5 @@ add_library(srsran_e1ap_common e1ap_asn1_packer.cpp log_helpers.cpp) target_link_libraries(srsran_e1ap_common e1ap_asn1) + +add_to_exported_libs(srsran_e1ap_common) diff --git a/lib/e1ap/cu_cp/CMakeLists.txt b/lib/e1ap/cu_cp/CMakeLists.txt index 9a4fb36473..2af3b7554e 100644 --- a/lib/e1ap/cu_cp/CMakeLists.txt +++ b/lib/e1ap/cu_cp/CMakeLists.txt @@ -16,3 +16,5 @@ add_library(srsran_e1ap_cu_cp ue_context/e1ap_cu_cp_ue_context.cpp) target_include_directories(srsran_e1ap_cu_cp PRIVATE ..) target_link_libraries(srsran_e1ap_cu_cp e1ap_asn1 srsran_e1ap_common srsran_cu_cp) + +add_to_exported_libs(srsran_e1ap_cu_cp) diff --git a/lib/f1ap/CMakeLists.txt b/lib/f1ap/CMakeLists.txt index 60b262c92c..6894a55590 100644 --- a/lib/f1ap/CMakeLists.txt +++ b/lib/f1ap/CMakeLists.txt @@ -12,3 +12,5 @@ add_subdirectory(gateways) add_library(srsran_f1ap_common f1ap_common_messages.cpp asn1_helpers.cpp f1ap_asn1_packer.cpp log_helpers.cpp) target_link_libraries(srsran_f1ap_common f1ap_asn1) + +add_to_exported_libs(srsran_f1ap_common) diff --git a/lib/f1ap/cu_cp/CMakeLists.txt b/lib/f1ap/cu_cp/CMakeLists.txt index 5d833ea045..4fb0c564df 100644 --- a/lib/f1ap/cu_cp/CMakeLists.txt +++ b/lib/f1ap/cu_cp/CMakeLists.txt @@ -18,3 +18,5 @@ add_library(srsran_f1ap_cu procedures/ue_context_release_procedure.cpp) target_include_directories(srsran_f1ap_cu PRIVATE ..) target_link_libraries(srsran_f1ap_cu srsran_support srsran_f1ap_common f1ap_asn1) + +add_to_exported_libs(srsran_f1ap_cu) diff --git a/lib/ngap/CMakeLists.txt b/lib/ngap/CMakeLists.txt index 97072c2100..2154272d51 100644 --- a/lib/ngap/CMakeLists.txt +++ b/lib/ngap/CMakeLists.txt @@ -31,3 +31,5 @@ add_library(srsran_ngap STATIC ${SOURCES}) target_link_libraries(srsran_ngap ngap_asn1 srsran_cu_cp srsran_support) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_to_exported_libs(srsran_ngap) diff --git a/lib/pdcp/CMakeLists.txt b/lib/pdcp/CMakeLists.txt index 52cc5ab28d..1e9e19576f 100644 --- a/lib/pdcp/CMakeLists.txt +++ b/lib/pdcp/CMakeLists.txt @@ -10,3 +10,5 @@ set(SOURCES pdcp_factory.cpp pdcp_entity_tx.cpp pdcp_entity_rx.cpp pdcp_pdu.cpp) add_library(srsran_pdcp STATIC ${SOURCES}) target_link_libraries(srsran_pdcp srsran_security srsran_instrumentation srsran_support) + +add_to_exported_libs(srsran_pdcp) diff --git a/lib/rrc/CMakeLists.txt b/lib/rrc/CMakeLists.txt index 7a96caae1c..ad3c3ae54c 100644 --- a/lib/rrc/CMakeLists.txt +++ b/lib/rrc/CMakeLists.txt @@ -27,4 +27,6 @@ set(SOURCES add_library(srsran_rrc STATIC ${SOURCES}) target_link_libraries(srsran_rrc srsran_up_resource_manager srsran_ue_security_manager srsran_security srsran_pdcp rrc_nr_asn1) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_to_exported_libs(srsran_rrc) diff --git a/lib/security/CMakeLists.txt b/lib/security/CMakeLists.txt index 86dbb410db..b37c1dd3e8 100644 --- a/lib/security/CMakeLists.txt +++ b/lib/security/CMakeLists.txt @@ -23,3 +23,5 @@ set(SOURCES add_library(srsran_security STATIC ${SOURCES}) target_include_directories(srsran_security PUBLIC ${SEC_INCLUDE_DIRS}) target_link_libraries(srsran_security ${SEC_LIBRARIES}) + +add_to_exported_libs(srsran_security) diff --git a/tests/test_doubles/e1ap/CMakeLists.txt b/tests/test_doubles/e1ap/CMakeLists.txt index 4dc64eb54f..79433d9616 100644 --- a/tests/test_doubles/e1ap/CMakeLists.txt +++ b/tests/test_doubles/e1ap/CMakeLists.txt @@ -9,3 +9,5 @@ add_library(e1ap_test_doubles e1ap_test_message_validators.cpp) set_target_properties(e1ap_test_doubles PROPERTIES UNITY_BUILD ON) target_link_libraries(e1ap_test_doubles srsran_support srslog e1ap_asn1) + +add_to_exported_libs(e1ap_test_doubles) diff --git a/tests/test_doubles/f1ap/CMakeLists.txt b/tests/test_doubles/f1ap/CMakeLists.txt index fc66e0f111..f222ebd9c7 100644 --- a/tests/test_doubles/f1ap/CMakeLists.txt +++ b/tests/test_doubles/f1ap/CMakeLists.txt @@ -9,3 +9,5 @@ add_library(f1ap_test_doubles f1ap_test_message_validators.cpp f1ap_test_messages.cpp) set_target_properties(f1ap_test_doubles PROPERTIES UNITY_BUILD ON) target_link_libraries(f1ap_test_doubles srsran_support srslog f1ap_asn1 rrc_test_doubles pdcp_test_doubles) + +add_to_exported_libs(f1ap_test_doubles) diff --git a/tests/test_doubles/ngap/CMakeLists.txt b/tests/test_doubles/ngap/CMakeLists.txt index 7c81cc6422..d0f0f1e743 100644 --- a/tests/test_doubles/ngap/CMakeLists.txt +++ b/tests/test_doubles/ngap/CMakeLists.txt @@ -8,3 +8,5 @@ add_library(ngap_test_doubles ngap_test_message_validators.cpp) target_link_libraries(ngap_test_doubles srsran_support srslog ngap_asn1) + +add_to_exported_libs(ngap_test_doubles) diff --git a/tests/test_doubles/pdcp/CMakeLists.txt b/tests/test_doubles/pdcp/CMakeLists.txt index 3bfd1b910e..ea50a710fe 100644 --- a/tests/test_doubles/pdcp/CMakeLists.txt +++ b/tests/test_doubles/pdcp/CMakeLists.txt @@ -9,3 +9,5 @@ add_library(pdcp_test_doubles pdcp_pdu_generator.cpp) set_target_properties(pdcp_test_doubles PROPERTIES UNITY_BUILD ON) target_link_libraries(pdcp_test_doubles srsran_support srslog) + +add_to_exported_libs(pdcp_test_doubles) diff --git a/tests/test_doubles/rrc/CMakeLists.txt b/tests/test_doubles/rrc/CMakeLists.txt index 5794b0ebaf..82ff5c494c 100644 --- a/tests/test_doubles/rrc/CMakeLists.txt +++ b/tests/test_doubles/rrc/CMakeLists.txt @@ -9,3 +9,5 @@ add_library(rrc_test_doubles rrc_test_messages.cpp rrc_test_message_validators.cpp) set_target_properties(rrc_test_doubles PROPERTIES UNITY_BUILD ON) target_link_libraries(rrc_test_doubles rrc_nr_asn1 srsran_support srslog) + +add_to_exported_libs(rrc_test_doubles) diff --git a/tests/unittests/cu_cp/CMakeLists.txt b/tests/unittests/cu_cp/CMakeLists.txt index ed36eb2976..92422b3ab3 100644 --- a/tests/unittests/cu_cp/CMakeLists.txt +++ b/tests/unittests/cu_cp/CMakeLists.txt @@ -29,6 +29,8 @@ add_library(cu_cp_test_helpers target_include_directories(cu_cp_test_helpers PRIVATE ${CMAKE_SOURCE_DIR}) target_link_libraries(cu_cp_test_helpers srsran_cu_cp srsran_support srslog f1ap_test_helpers e1ap_test_helpers f1ap_asn1 ngap_asn1 e1ap_asn1) +add_to_exported_libs(cu_cp_test_helpers) + add_executable(cu_cp_test cu_cp_connectivity_test.cpp diff --git a/tests/unittests/e1ap/common/CMakeLists.txt b/tests/unittests/e1ap/common/CMakeLists.txt index d3784aadaa..e0c2187d34 100644 --- a/tests/unittests/e1ap/common/CMakeLists.txt +++ b/tests/unittests/e1ap/common/CMakeLists.txt @@ -23,3 +23,5 @@ target_link_libraries(e1ap_asn1_packer_test gtest_main) target_include_directories(e1ap_asn1_packer_test PRIVATE ${CMAKE_SOURCE_DIR}) gtest_discover_tests(e1ap_asn1_packer_test) + +add_to_exported_libs(e1ap_test_helpers) diff --git a/tests/unittests/f1ap/common/CMakeLists.txt b/tests/unittests/f1ap/common/CMakeLists.txt index 6123fc6f31..c8fa607e29 100644 --- a/tests/unittests/f1ap/common/CMakeLists.txt +++ b/tests/unittests/f1ap/common/CMakeLists.txt @@ -23,3 +23,5 @@ target_link_libraries(f1ap_asn1_packer_test gtest_main) target_include_directories(f1ap_asn1_packer_test PRIVATE ${CMAKE_SOURCE_DIR}) gtest_discover_tests(f1ap_asn1_packer_test) + +add_to_exported_libs(f1ap_test_helpers) diff --git a/tests/unittests/ngap/CMakeLists.txt b/tests/unittests/ngap/CMakeLists.txt index 001a62c1ec..d5f6a04dd5 100644 --- a/tests/unittests/ngap/CMakeLists.txt +++ b/tests/unittests/ngap/CMakeLists.txt @@ -29,3 +29,5 @@ target_include_directories(ngap_test PRIVATE ${CMAKE_SOURCE_DIR}) set_target_properties(ngap_test PROPERTIES UNITY_BUILD ON) target_link_libraries(ngap_test ngap_test_helpers srsran_ngap srsran_support ngap_asn1 srsran_ran srslog gtest gtest_main) gtest_discover_tests(ngap_test PROPERTIES "LABELS;ngap") + +add_to_exported_libs(ngap_test_helpers) From b35ba3bee51cbd4b5eecd69bfd450b1de511c831 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 20 Sep 2024 12:43:04 +0200 Subject: [PATCH 119/174] ran: review DCI size configuration validator --- include/srsran/ran/pdcch/dci_packing.h | 3 +- lib/ran/pdcch/dci_packing.cpp | 371 +++++++----------- lib/scheduler/config/ue_configuration.cpp | 12 +- .../ran/pdcch/dci_packing_validator_test.cpp | 216 ++++------ 4 files changed, 231 insertions(+), 371 deletions(-) diff --git a/include/srsran/ran/pdcch/dci_packing.h b/include/srsran/ran/pdcch/dci_packing.h index be1fe58a15..98fcc0a581 100644 --- a/include/srsran/ran/pdcch/dci_packing.h +++ b/include/srsran/ran/pdcch/dci_packing.h @@ -11,6 +11,7 @@ #pragma once #include "srsran/adt/bounded_bitset.h" +#include "srsran/adt/expected.h" #include "srsran/adt/optional.h" #include "srsran/adt/static_vector.h" #include "srsran/ran/dmrs.h" @@ -1133,6 +1134,6 @@ struct dci_rar_configuration { dci_payload dci_rar_pack(const dci_rar_configuration& config); /// Validates a DCI configuration for the DCI size alignment procedure. -bool validate_dci_size_config(const dci_size_config& config); +error_type validate_dci_size_config(const dci_size_config& config); } // namespace srsran diff --git a/lib/ran/pdcch/dci_packing.cpp b/lib/ran/pdcch/dci_packing.cpp index cbcc0c172b..35dceb4fc5 100644 --- a/lib/ran/pdcch/dci_packing.cpp +++ b/lib/ran/pdcch/dci_packing.cpp @@ -9,6 +9,7 @@ */ #include "srsran/ran/pdcch/dci_packing.h" +#include "srsran/adt/interval.h" #include "srsran/adt/span.h" #include "srsran/ran/pdcch/dci_packing_formatters.h" #include "srsran/support/math_utils.h" @@ -60,19 +61,6 @@ static bool max_cbg_tb_is_valid(unsigned max_cbg_tb) } } -// Checks that the number of SRS ports value is valid, as per TS38.331 Section 6.3.2, Information Element SRS-Config. -static bool nof_srs_ports_is_valid(unsigned max_cbg_tb) -{ - switch (max_cbg_tb) { - case 1: - case 2: - case 4: - return true; - default: - return false; - } -} - // Computes the number of information bits before padding for a DCI format 0_0 message. static dci_0_0_size dci_f0_0_bits_before_padding(unsigned N_rb_ul_bwp) { @@ -516,169 +504,9 @@ static dci_1_1_size dci_f1_1_bits_before_padding(const dci_size_config& dci_conf } static void assert_dci_size_config(const dci_size_config& config) -{ // Asserts for all DCI formats. - srsran_assert((config.dl_bwp_initial_bw > 0) && (config.dl_bwp_initial_bw <= MAX_RB), - "The initial DL BWP bandwidth, i.e., {} must be within the range [1, {}].", - config.dl_bwp_initial_bw, - MAX_RB); - - srsran_assert((config.ul_bwp_initial_bw > 0) && (config.ul_bwp_initial_bw <= MAX_RB), - "The initial UL BWP bandwidth, i.e., {} must be within the range [1, {}].", - config.ul_bwp_initial_bw, - MAX_RB); - - srsran_assert(config.coreset0_bw <= MAX_RB, - "The CORESET 0 bandwidth, i.e., {} must be within the range [0, {}].", - config.coreset0_bw, - MAX_RB); - - srsran_assert(!config.sul_configured, "SUL is not currently supported."); - - // Asserts for fallback DCI formats on a UE-specific search space. - if (config.dci_0_0_and_1_0_ue_ss) { - srsran_assert((config.dl_bwp_active_bw > 0) && (config.dl_bwp_active_bw <= MAX_RB), - "The active DL BWP bandwidth, i.e., {} must be within the range [1, {}].", - config.dl_bwp_active_bw, - MAX_RB); - - srsran_assert((config.ul_bwp_active_bw > 0) && (config.ul_bwp_active_bw <= MAX_RB), - "The active UL BWP bandwidth, i.e., {} must be within the range [1, {}].", - config.ul_bwp_active_bw, - MAX_RB); - } - - // Asserts for non-fallback DCI formats. - if (config.dci_0_1_and_1_1_ue_ss) { - srsran_assert((config.nof_ul_bwp_rrc <= 4), - "The number of UL BWP configured by higher layers, i.e., {}, cannot exceed 4.", - config.nof_ul_bwp_rrc); - srsran_assert((config.nof_dl_bwp_rrc <= 4), - "The number of DL BWP configured by higher layers, i.e., {}, cannot exceed 4.", - config.nof_dl_bwp_rrc); - - srsran_assert((config.nof_ul_time_domain_res > 0) && (config.nof_ul_time_domain_res <= 16), - "The number of UL time domain resource allocations, i.e., {} must be within the range [1, 16].", - config.nof_ul_time_domain_res); - - srsran_assert((config.nof_dl_time_domain_res > 0) && (config.nof_dl_time_domain_res <= 16), - "The number of DL time domain resource allocations, i.e., {} must be within the range [1, 16].", - config.nof_dl_time_domain_res); - - srsran_assert((config.nof_aperiodic_zp_csi <= 3), - "The number of aperiodic ZP CSI-RS resource sets, i.e., {}, cannot be larger than 3.", - config.nof_aperiodic_zp_csi); - - srsran_assert((config.nof_pdsch_ack_timings > 0) && (config.nof_pdsch_ack_timings <= 8), - "The number of PDSCH HARQ-ACK timings, i.e., {}, must be within the range [1, 8].", - config.nof_pdsch_ack_timings); - - srsran_assert((config.report_trigger_size <= 6), - "The report trigger size, i.e., {}, cannot be larger than 6.", - config.report_trigger_size); - - srsran_assert(!config.max_cbg_tb_pusch.has_value() || (max_cbg_tb_is_valid(config.max_cbg_tb_pusch.value())), - "Invalid Maximum CBG per PUSCH TB, i.e., {}. Valid options: 2, 4, 6, 8.", - config.max_cbg_tb_pusch.value()); - - srsran_assert(!config.max_cbg_tb_pdsch.has_value() || (max_cbg_tb_is_valid(config.max_cbg_tb_pdsch.value())), - "Invalid Maximum CBG per PDSCH TB, i.e., {}. Valid options: 2, 4, 6, 8.", - config.max_cbg_tb_pdsch.value()); - - // Asserts for transform precoding. - srsran_assert(!config.transform_precoding_enabled || !config.pusch_dmrs_A_type.has_value() || - (config.pusch_dmrs_A_type != dmrs_config_type::type2), - "UL DM-RS configuration type 2 cannot be used with transform precoding."); - srsran_assert(!config.transform_precoding_enabled || !config.pusch_dmrs_B_type.has_value() || - (config.pusch_dmrs_B_type != dmrs_config_type::type2), - "UL DM-RS configuration type 2 cannot be used with transform precoding."); - - srsran_assert((config.pdsch_harq_ack_cb != pdsch_harq_ack_codebook::dynamic) || - config.dynamic_dual_harq_ack_cb.has_value(), - "Dynamic dual HARQ-ACK codebook flag is required for dynamic PDSCH HARQ-ACK codebook."); - - if (config.pusch_res_allocation_type != resource_allocation::resource_allocation_type_1) { - // Asserts for UL resource allocation type 0. - srsran_assert(config.nof_ul_rb_groups.has_value(), - "The number of UL RBGs is required for resource allocation type 0."); - srsran_assert((config.nof_ul_rb_groups.value() > 0) && (config.nof_ul_rb_groups.value() <= MAX_NOF_RBGS), - "The number of UL RBGs, i.e., {}, must be within the range [1, {}].", - config.nof_ul_rb_groups.value(), - MAX_NOF_RBGS); - } - - if (config.pdsch_res_allocation_type != resource_allocation::resource_allocation_type_1) { - // Asserts for DL resource allocation type 0. - srsran_assert(config.nof_dl_rb_groups.has_value(), - "The number of DL RBGs is required for resource allocation type 0."); - srsran_assert((config.nof_dl_rb_groups.value() > 0) && (config.nof_dl_rb_groups.value() <= MAX_NOF_RBGS), - "The number of DL RBGs, i.e., {}, must be within the range [1, {}].", - config.nof_dl_rb_groups.value(), - MAX_NOF_RBGS); - } - - // Asserts for DL resource allocation type 1. - srsran_assert((config.pdsch_res_allocation_type == resource_allocation::resource_allocation_type_0) || - config.interleaved_vrb_prb_mapping.has_value(), - "Interleaved VRB to PRB mapping flag is required for PDSCH resource allocation type 1."); - - if (config.tx_config_non_codebook) { - // Asserts for non-codebook based transmission. - srsran_assert(config.pusch_max_layers.has_value(), - "Maximum number of PUSCH layers is required for non-codebook transmission."); - - srsran_assert((config.pusch_max_layers.value() > 0) && (config.pusch_max_layers.value() <= 4), - "Maximum number of PUSH layers, i.e., {}, must be within the valid range [1, 4].", - config.pusch_max_layers.value()); - - srsran_assert((config.nof_srs_resources > 0) && (config.nof_srs_resources <= 4), - "Number of SRS resources, i.e., {}, must be within the range [1, 4] for non-codebook transmission.", - config.nof_srs_resources); - - // Temporary assertion, until UL MIMO is supported. - srsran_assert((config.pusch_max_layers.value() == 1), "Multiple layers on PUSCH are not currently supported."); - } else { - // Asserts for codebook-based transmission. - srsran_assert(config.max_rank.has_value(), "Maximum rank is required for codebook transmission."); - - srsran_assert((config.max_rank.value() > 0) && (config.max_rank.value() <= 4), - "Maximum rank, i.e., {}, must be within the valid range [1, 4].", - config.max_rank.value()); - - srsran_assert(config.nof_srs_ports.has_value(), - "Number of SRS antenna ports is required for codebook transmission."); - - srsran_assert(nof_srs_ports_is_valid(config.nof_srs_ports.value()), - "Invalid number of SRS ports, i.e., {}. Valid options: 1, 2, 4.", - config.nof_srs_ports.value()); - - srsran_assert((config.max_rank.value() <= config.nof_srs_ports.value()), - "Maximum rank, i.e., {}, cannot be larger than the number of SRS antenna ports, i.e., {}.", - config.max_rank.value(), - config.nof_srs_ports.value()); - - srsran_assert((config.nof_srs_resources > 0) && (config.nof_srs_resources <= 2), - "Number of SRS resources, i.e., {}, must be within the range [1, 2] for codebook transmission.", - config.nof_srs_resources); - - srsran_assert((config.nof_srs_ports.value() == 1) || config.cb_subset.has_value(), - "Codebook subset is required for codebook transmission with multiple antenna ports."); - - // Temporary assertion, until UL precoding is supported. - srsran_assert((config.nof_srs_ports.value() == 1), "UL precoding is not currently supported."); - } - - srsran_assert(!config.ptrs_uplink_configured || config.transform_precoding_enabled || - (!config.tx_config_non_codebook && (config.max_rank.value() == 1)), - "PT-RS with more than one DM-RS is not currently supported."); - - srsran_assert((config.pusch_dmrs_A_type.has_value() && config.pusch_dmrs_A_max_len.has_value()) || - (config.pusch_dmrs_B_type.has_value() && config.pusch_dmrs_B_max_len.has_value()), - "At least one PUSCH DM-RS mapping (type A or type B) must be configured."); - - srsran_assert((config.pdsch_dmrs_A_type.has_value() && config.pdsch_dmrs_A_max_len.has_value()) || - (config.pdsch_dmrs_B_type.has_value() && config.pdsch_dmrs_B_max_len.has_value()), - "At least one PDSCH DM-RS mapping (type A or type B) must be configured."); - } +{ + error_type error = validate_dci_size_config(config); + srsran_assert(error.has_value(), "Invalid DCI size configuration: {}", error.error()); } dci_sizes srsran::get_dci_sizes(const dci_size_config& config) @@ -1365,7 +1193,7 @@ dci_payload srsran::dci_0_1_pack(const dci_0_1_configuration& config) // Assert total payload size. srsran_assert(units::bits(payload.size()) == config.payload_size.total, - "Constructed payload size (i.e., {}) does not match expected payload size. Expected sizes:\n{}", + "Constructed payload size {} does not match expected payload size. Expected sizes:\n{}", units::bits(payload.size()), config.payload_size); @@ -1511,7 +1339,7 @@ dci_payload srsran::dci_1_1_pack(const dci_1_1_configuration& config) // Assert total payload size. srsran_assert(units::bits(payload.size()) == config.payload_size.total, - "Constructed payload size (i.e., {}) does not match expected payload size. Expected sizes:\n{}", + "Constructed payload size {} does not match expected payload size. Expected sizes:\n{}", units::bits(payload.size()), config.payload_size); @@ -1543,72 +1371,112 @@ dci_payload srsran::dci_rar_pack(const dci_rar_configuration& config) return payload; } -bool srsran::validate_dci_size_config(const dci_size_config& config) +error_type srsran::validate_dci_size_config(const dci_size_config& config) { + // Constants. + static constexpr unsigned max_nof_bwp_rrc = 4; + static constexpr unsigned max_nof_time_domain_res = 16; + + // Valid bandwidth range. + static constexpr interval bwp_bw_range(1, MAX_RB); + static constexpr interval coreset0_bw_range(0, MAX_RB); + static constexpr interval nof_bwp_rrc_range(0, max_nof_bwp_rrc); + static constexpr interval nof_time_domain_res_range(1, max_nof_time_domain_res); + static constexpr interval non_codebook_nof_srs_res_range(1, 4); + static constexpr interval codebook_nof_srs_res_range(1, 2); + static constexpr interval nof_aperiodic_zp_csi_range(0, 3); + static constexpr interval report_trigger_size_range(0, 6); + static constexpr interval nof_pdsch_ack_timings_range(1, 8); + static constexpr interval nof_rb_groups_range(1, MAX_NOF_RBGS); + static constexpr interval pusch_max_layers_range(1, 4); + static constexpr interval max_rank_range(1, 4); + // Check that UL and DL BWP and CORESET 0 bandwidths are within range. - if ((config.dl_bwp_initial_bw > MAX_RB) || (config.ul_bwp_initial_bw > MAX_RB) || (config.coreset0_bw > MAX_RB)) { - return false; + if (!bwp_bw_range.contains(config.dl_bwp_initial_bw)) { + return make_unexpected( + fmt::format("DL initial BWP bandwidth {} is out of range {}.", config.dl_bwp_initial_bw, bwp_bw_range)); } - - // Fallback DCI formats monitored on a CSS need the initial UL and DL BWP bandwidth. - if ((config.dl_bwp_initial_bw == 0) || (config.ul_bwp_initial_bw == 0)) { - return false; + if (!bwp_bw_range.contains(config.ul_bwp_initial_bw)) { + return make_unexpected( + fmt::format("UL initial BWP bandwidth {} is out of range {}.", config.ul_bwp_initial_bw, bwp_bw_range)); + } + if (!coreset0_bw_range.contains(config.coreset0_bw)) { + return make_unexpected( + fmt::format("CORESET0 bandwidth {} is out of range {}.", config.coreset0_bw, coreset0_bw_range)); } // Supplementary Uplink is not currently supported by the DCI size alignment procedure. if (config.sul_configured) { - return false; + return make_unexpected(fmt::format("SUL is not currently supported by the DCI size alignment procedure.")); } // Checks pertaining to any DCI format on a USS. if (config.dci_0_0_and_1_0_ue_ss || config.dci_0_1_and_1_1_ue_ss) { // DCI formats monitored on a USS need the active UL and DL BWP bandwidth. - if ((config.dl_bwp_active_bw == 0) || (config.dl_bwp_active_bw > MAX_RB) || (config.ul_bwp_active_bw == 0) || - (config.ul_bwp_active_bw > MAX_RB)) { - return false; + if (!bwp_bw_range.contains(config.dl_bwp_active_bw)) { + return make_unexpected( + fmt::format("DL active BWP bandwidth {} is out of range {}.", config.dl_bwp_active_bw, bwp_bw_range)); + } + if (!bwp_bw_range.contains(config.ul_bwp_active_bw)) { + return make_unexpected( + fmt::format("UL active BWP bandwidth {} is out of range {}.", config.ul_bwp_active_bw, bwp_bw_range)); } } // Checks pertaining to non-fallback DCI formats. if (config.dci_0_1_and_1_1_ue_ss) { // Number of BWP configured by higher layers cannot exceed 4. - if ((config.nof_ul_bwp_rrc > 4) || config.nof_dl_bwp_rrc > 4) { - return false; + if (!nof_bwp_rrc_range.contains(config.nof_ul_bwp_rrc)) { + return make_unexpected(fmt::format( + "The number of RRC configured UL BWP {} is out of range {}.", config.nof_ul_bwp_rrc, nof_bwp_rrc_range)); + } + if (!nof_bwp_rrc_range.contains(config.nof_dl_bwp_rrc)) { + return make_unexpected(fmt::format( + "The number of RRC configured DL BWP {} is out of range {}.", config.nof_dl_bwp_rrc, nof_bwp_rrc_range)); } // Number of UL time domain resource allocations must be within the valid range {1, ..., 16} - if ((config.nof_ul_time_domain_res == 0) || (config.nof_ul_time_domain_res > 16)) { - return false; + if (!nof_time_domain_res_range.contains(config.nof_ul_time_domain_res)) { + return make_unexpected(fmt::format("The number of UL time domain resources {} is out of range {}.", + config.nof_ul_time_domain_res, + nof_time_domain_res_range)); } // Number of DL time domain resource allocations must be within the valid range {1, ..., 16} - if ((config.nof_dl_time_domain_res == 0) || (config.nof_dl_time_domain_res > 16)) { - return false; + if (!nof_time_domain_res_range.contains(config.nof_dl_time_domain_res)) { + return make_unexpected(fmt::format("The number of DL time domain resources {} is out of range {}.", + config.nof_dl_time_domain_res, + nof_time_domain_res_range)); } // Size of the DCI request field, determined by the higher layer parameter reportTriggerSize, cannot exceed 6. - if (config.report_trigger_size > 6) { - return false; + if (!report_trigger_size_range.contains(config.report_trigger_size)) { + return make_unexpected(fmt::format( + "CSI report trigger size {} is out of range {}.", config.report_trigger_size, report_trigger_size_range)); } // Number of aperiodic ZP CSI-RS resource sets cannot exceed 3. - if (config.nof_aperiodic_zp_csi > 3) { - return false; + if (!nof_aperiodic_zp_csi_range.contains(config.nof_aperiodic_zp_csi)) { + return make_unexpected(fmt::format("The number of aperiodic ZP-CSI resource sets {} is out of range {}.", + config.nof_aperiodic_zp_csi, + nof_aperiodic_zp_csi_range)); } // Number of PDSCH to DL ACK timings exceeds the valid range {1, ..., 8}. - if ((config.nof_pdsch_ack_timings == 0) || (config.nof_pdsch_ack_timings > 8)) { - return false; + if (!nof_pdsch_ack_timings_range.contains(config.nof_pdsch_ack_timings)) { + return make_unexpected(fmt::format("The number of HARQ-ACK feedback timing entries {} is out of range {}.", + config.nof_pdsch_ack_timings, + nof_pdsch_ack_timings_range)); } // Requirements if transform precoding is enabled. if (config.transform_precoding_enabled) { // With transform precoding enabled for the UL, the PUSCH DM-RS configuration can only be type 1. if (config.pusch_dmrs_A_type.has_value() && (config.pusch_dmrs_A_type == dmrs_config_type::type2)) { - return false; + return make_unexpected("PUSCH DM-RS (A) Type2 is not supported with transform precoding."); } if (config.pusch_dmrs_B_type.has_value() && (config.pusch_dmrs_B_type == dmrs_config_type::type2)) { - return false; + return make_unexpected("PUSCH DM-RS (B) Type2 is not supported with transform precoding."); } } @@ -1616,25 +1484,31 @@ bool srsran::validate_dci_size_config(const dci_size_config& config) if (config.pdsch_harq_ack_cb == pdsch_harq_ack_codebook::dynamic) { // The dynamic dual HARQ-ACK codebook flag is required. if (!config.dynamic_dual_harq_ack_cb.has_value()) { - return false; + return make_unexpected("Dynamic dual HARQ-ACK codebook flag is required for dynamic PDSCH HARQ-ACK codebook."); } } // Requirements for UL resource allocation type 0. if (config.pusch_res_allocation_type != resource_allocation::resource_allocation_type_1) { // Number of UL RBGs is required, and must not exceed the valid range. - if (!config.nof_ul_rb_groups.has_value() || (config.nof_ul_rb_groups.value() > MAX_NOF_RBGS) || - (config.nof_ul_rb_groups.value() == 0)) { - return false; + if (!config.nof_ul_rb_groups.has_value()) { + return make_unexpected("The number of UL RBGs is required for resource allocation type 0."); + } + if (!nof_rb_groups_range.contains(config.nof_ul_rb_groups.value())) { + return make_unexpected(fmt::format( + "The number of UL RBGs {} is out of range {}.", config.nof_ul_rb_groups.value(), nof_rb_groups_range)); } } // Requirements for DL resource allocation type 0. if (config.pdsch_res_allocation_type != resource_allocation::resource_allocation_type_1) { // Number of DL RBGs is required, and must not exceed the valid range. - if (!config.nof_dl_rb_groups.has_value() || (config.nof_dl_rb_groups.value() > MAX_NOF_RBGS) || - (config.nof_dl_rb_groups.value() == 0)) { - return false; + if (!config.nof_dl_rb_groups.has_value()) { + return make_unexpected("The number of DL RBGs is required for resource allocation type 0."); + } + if (!nof_rb_groups_range.contains(config.nof_dl_rb_groups.value())) { + return make_unexpected(fmt::format( + "The number of DL RBGs {} is out of range {}.", config.nof_dl_rb_groups.value(), nof_rb_groups_range)); } } @@ -1642,42 +1516,67 @@ bool srsran::validate_dci_size_config(const dci_size_config& config) if (config.pdsch_res_allocation_type != resource_allocation::resource_allocation_type_0) { // Interleaved VRB to PRB mapping flag is required. if (!config.interleaved_vrb_prb_mapping.has_value()) { - return false; + return make_unexpected("Interleaved VRB to PRB mapping flag is required for PDSCH resource allocation type 1."); } } // Requirements for non-codebook based transmission. if (config.tx_config_non_codebook) { - // PUSCH max number of layers is required, and it must be set to one. - if (!config.pusch_max_layers.has_value() || (config.pusch_max_layers.value() != 1)) { - return false; + // PUSCH max number of layers is required. + if (!config.pusch_max_layers) { + return make_unexpected("Maximum number of PUSCH layers is required for non-codebook transmission."); + } + + // PUSCH max number of layers must be within the valid range. + if (!pusch_max_layers_range.contains(config.pusch_max_layers.value())) { + return make_unexpected(fmt::format("Maximum number of PUSCH layers {} is out of range {}.", + config.pusch_max_layers.value(), + pusch_max_layers_range)); + } + + // Multiple layers on PUSCH are not currently supported. + if (config.pusch_max_layers.value() != 1) { + return make_unexpected("Multiple layers on PUSCH are not currently supported."); } // For non-codebook based transmission, the number of SRS resources must be within the valid range {1, ..., 4}. - if ((config.nof_srs_resources == 0) || (config.nof_srs_resources > 4)) { - return false; + if (!non_codebook_nof_srs_res_range.contains(config.nof_srs_resources)) { + return make_unexpected( + fmt::format("The number of SRS resources {} is out of range {} for non-codebook transmission.", + config.nof_srs_resources, + non_codebook_nof_srs_res_range)); } // Requirements for codebook based transmission. } else { - // Maximum rank is required for codebook-based transmission, and it must be within the valid range {1, ..., 4}. - if (!config.max_rank.has_value() || (config.max_rank.value() == 0) || (config.max_rank.value() > 4)) { - return false; + // Maximum rank is required for codebook-based transmission. + if (!config.max_rank.has_value()) { + return make_unexpected("Maximum rank is required for codebook transmission."); + } + + // Maximum rank must be within the valid range {1, ..., 4}. + if (!max_rank_range.contains(config.max_rank.value())) { + return make_unexpected(fmt::format("Maximum rank {} is out of range {}.", config.max_rank, max_rank_range)); } // For codebook based transmission, the number of SRS ports is required. if (!config.nof_srs_ports.has_value()) { - return false; + return make_unexpected("Number of SRS ports is required for codebook transmission."); } // For codebook based transmission, the number of SRS resources must be within the valid range {1, 2}. - if ((config.nof_srs_resources == 0) || (config.nof_srs_resources > 2)) { - return false; + if (!codebook_nof_srs_res_range.contains(config.nof_srs_resources)) { + return make_unexpected( + fmt::format("The number of SRS resources {} is out of range {} for codebook transmission.", + config.nof_srs_resources, + codebook_nof_srs_res_range)); } // Maximum rank cannot be greater than the number of SRS ports. if (config.max_rank.value() > config.nof_srs_ports.value()) { - return false; + return make_unexpected(fmt::format("Maximum rank {} cannot be larger than the number of SRS antenna ports {}.", + config.max_rank, + config.nof_srs_ports)); } // The number of SRS ports must be a valid value {1, 2, 4}. @@ -1688,47 +1587,49 @@ bool srsran::validate_dci_size_config(const dci_size_config& config) case 4: // Codebook subset is required for codebook based transmission with more than one antenna port. if (!config.cb_subset.has_value()) { - return false; + return make_unexpected( + "Codebook subset is required for codebook transmission with multiple antenna ports."); } - // Currently, UL precoding with multiple antenna ports is not supported. - return false; + break; default: - return false; + return make_unexpected( + fmt::format("The number of SRS ports {} is neither 1, 2, nor 4.", config.nof_srs_ports)); } } // PT-RS to DM-RS association is not currently supported. - if (config.ptrs_uplink_configured && !config.transform_precoding_enabled && - (config.tx_config_non_codebook || (config.max_rank.value() > 1))) { - return false; + if (config.ptrs_uplink_configured) { + return make_unexpected("PT-RS is not currently supported."); } // At least one PUSCH DM-RS mapping must be configured. if ((!config.pusch_dmrs_A_type.has_value() || !config.pusch_dmrs_A_max_len.has_value()) && (!config.pusch_dmrs_B_type.has_value() || !config.pusch_dmrs_B_max_len.has_value())) { - return false; + return make_unexpected("At least one PUSCH DM-RS mapping (type A or type B) must be configured."); } // At least one PDSCH DM-RS mapping must be configured. if ((!config.pdsch_dmrs_A_type.has_value() || !config.pdsch_dmrs_A_max_len.has_value()) && (!config.pdsch_dmrs_B_type.has_value() || !config.pdsch_dmrs_B_max_len.has_value())) { - return false; + return make_unexpected("At least one PDSCH DM-RS mapping (type A or type B) must be configured."); } if (config.max_cbg_tb_pusch.has_value()) { // The Maximum PUSCH CBG per TB must be set to a valid value. if (!max_cbg_tb_is_valid(config.max_cbg_tb_pusch.value())) { - return false; + return make_unexpected( + fmt::format("The maximum CBG per PUSCH TB {} is neither 2, 4, 6, nor 8.", config.max_cbg_tb_pusch.value())); } } if (config.max_cbg_tb_pdsch.has_value()) { // The Maximum PDSCH CBG per TB must be set to a valid value. if (!max_cbg_tb_is_valid(config.max_cbg_tb_pdsch.value())) { - return false; + return make_unexpected( + fmt::format("The maximum CBG per PDSCH TB {} is neither 2, 4, 6, nor 8.", config.max_cbg_tb_pdsch.value())); } } } - return true; + return default_success_t(); } diff --git a/lib/scheduler/config/ue_configuration.cpp b/lib/scheduler/config/ue_configuration.cpp index dc2a4dd337..13bcd1395e 100644 --- a/lib/scheduler/config/ue_configuration.cpp +++ b/lib/scheduler/config/ue_configuration.cpp @@ -620,8 +620,16 @@ void ue_cell_configuration::reconfigure(const serving_cell_config& cell_cfg_ded_ // Compute DCI sizes for (search_space_info& ss : search_spaces) { ss.dci_sz_cfg = get_dci_size_config(*this, multi_cells_configured, ss.cfg->get_id()); - srsran_assert( - validate_dci_size_config(ss.dci_sz_cfg), "Invalid DCI size configuration for SearchSpace={}", ss.cfg->get_id()); + + // Verify the DCI size configuration is valid. + const error_type dci_size_valid = validate_dci_size_config(ss.dci_sz_cfg); + if (!dci_size_valid.has_value()) { + srsran_assert(!dci_size_valid.has_value(), + "Invalid DCI size configuration for SearchSpace={}: {}", + ss.cfg->get_id(), + dci_size_valid.error()); + } + ss.dci_sz = get_dci_sizes(ss.dci_sz_cfg); } diff --git a/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp b/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp index 0d5d59276f..321abed75f 100644 --- a/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp +++ b/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp @@ -21,13 +21,13 @@ static constexpr unsigned MAX_NOF_RBGS = 18; // expected message. static void test_validator(const dci_size_config& invalid_config, const std::string& expected_assert_message) { + const error_type error = validate_dci_size_config(invalid_config); + // Make sure the configuration is invalid. - ASSERT_FALSE(validate_dci_size_config(invalid_config)); + ASSERT_FALSE(error); // Perform size alignment procedure. -#ifdef ASSERTS_ENABLED - ASSERT_DEATH({ get_dci_sizes(invalid_config); }, expected_assert_message); -#endif // ASSERTS_ENABLED + ASSERT_EQ(error.error(), expected_assert_message); } namespace { @@ -200,9 +200,7 @@ TEST_F(DciValidatorFallbackFixture, BadInitialBandwidth) dci_size_config config = get_base_dci_config(); config.ul_bwp_initial_bw = MAX_RB + 1; std::string assert_message = - fmt::format(R"(The initial UL BWP bandwidth\, i\.e\.\, {} must be within the range \[1\, {}\]\.)", - config.ul_bwp_initial_bw, - MAX_RB); + fmt::format("UL initial BWP bandwidth {} is out of range [1..{}].", config.ul_bwp_initial_bw, MAX_RB); test_validator(config, assert_message); } @@ -210,9 +208,7 @@ TEST_F(DciValidatorFallbackFixture, BadInitialBandwidth) dci_size_config config = get_base_dci_config(); config.ul_bwp_initial_bw = 0; std::string assert_message = - fmt::format(R"(The initial UL BWP bandwidth\, i\.e\.\, {} must be within the range \[1\, {}\]\.)", - config.ul_bwp_initial_bw, - MAX_RB); + fmt::format("UL initial BWP bandwidth {} is out of range [1..{}].", config.ul_bwp_initial_bw, MAX_RB); test_validator(config, assert_message); } @@ -220,9 +216,7 @@ TEST_F(DciValidatorFallbackFixture, BadInitialBandwidth) dci_size_config config = get_base_dci_config(); config.dl_bwp_initial_bw = MAX_RB + 1; std::string assert_message = - fmt::format(R"(The initial DL BWP bandwidth\, i\.e\.\, {} must be within the range \[1\, {}\]\.)", - config.dl_bwp_initial_bw, - MAX_RB); + fmt::format("DL initial BWP bandwidth {} is out of range [1..{}].", config.dl_bwp_initial_bw, MAX_RB); test_validator(config, assert_message); } @@ -230,17 +224,15 @@ TEST_F(DciValidatorFallbackFixture, BadInitialBandwidth) dci_size_config config = get_base_dci_config(); config.dl_bwp_initial_bw = 0; std::string assert_message = - fmt::format(R"(The initial DL BWP bandwidth\, i\.e\.\, {} must be within the range \[1\, {}\]\.)", - config.dl_bwp_initial_bw, - MAX_RB); + fmt::format("DL initial BWP bandwidth {} is out of range [1..{}].", config.dl_bwp_initial_bw, MAX_RB); test_validator(config, assert_message); } { - dci_size_config config = get_base_dci_config(); - config.coreset0_bw = MAX_RB + 1; - std::string assert_message = fmt::format( - R"(The CORESET 0 bandwidth\, i\.e\.\, {} must be within the range \[0\, {}\]\.)", config.coreset0_bw, MAX_RB); + dci_size_config config = get_base_dci_config(); + config.coreset0_bw = MAX_RB + 1; + std::string assert_message = + fmt::format("CORESET0 bandwidth {} is out of range [0..{}].", config.coreset0_bw, MAX_RB); test_validator(config, assert_message); } @@ -253,9 +245,7 @@ TEST_F(DciValidatorFallbackFixture, BadActiveBandwidth) dci_size_config config = get_base_dci_config(); config.ul_bwp_active_bw = MAX_RB + 1; std::string assert_message = - fmt::format(R"(The active UL BWP bandwidth\, i\.e\.\, {} must be within the range \[1\, {}\]\.)", - config.ul_bwp_active_bw, - MAX_RB); + fmt::format("UL active BWP bandwidth {} is out of range [1..{}].", config.ul_bwp_active_bw, MAX_RB); test_validator(config, assert_message); } @@ -264,9 +254,7 @@ TEST_F(DciValidatorFallbackFixture, BadActiveBandwidth) dci_size_config config = get_base_dci_config(); config.dl_bwp_active_bw = MAX_RB + 1; std::string assert_message = - fmt::format(R"(The active DL BWP bandwidth\, i\.e\.\, {} must be within the range \[1\, {}\]\.)", - config.dl_bwp_active_bw, - MAX_RB); + fmt::format("DL active BWP bandwidth {} is out of range [1..{}].", config.dl_bwp_active_bw, MAX_RB); test_validator(config, assert_message); } @@ -277,7 +265,7 @@ TEST_F(DciValidatorFallbackFixture, SupplementaryUplinkNotSupported) { dci_size_config config = get_base_dci_config(); config.sul_configured = true; - std::string assert_message = fmt::format(R"(SUL is not currently supported\.)"); + std::string assert_message = fmt::format("SUL is not currently supported by the DCI size alignment procedure."); test_validator(config, assert_message); } @@ -286,19 +274,19 @@ TEST_F(DciValidatorFallbackFixture, SupplementaryUplinkNotSupported) TEST_F(DciValidatorNonFallbackFixture, BadNofBwpConfiguredByHigherLayers) { { - dci_size_config config = get_base_dci_config(); - config.nof_ul_bwp_rrc = 5; - std::string assert_message = fmt::format( - R"(The number of UL BWP configured by higher layers\, i\.e\.\, {}\, cannot exceed 4\.)", config.nof_ul_bwp_rrc); + dci_size_config config = get_base_dci_config(); + config.nof_ul_bwp_rrc = 5; + std::string assert_message = + fmt::format("The number of RRC configured UL BWP {} is out of range [0..4].", config.nof_ul_bwp_rrc); test_validator(config, assert_message); } { - dci_size_config config = get_base_dci_config(); - config.nof_dl_bwp_rrc = 5; - std::string assert_message = fmt::format( - R"(The number of DL BWP configured by higher layers\, i\.e\.\, {}\, cannot exceed 4\.)", config.nof_dl_bwp_rrc); + dci_size_config config = get_base_dci_config(); + config.nof_dl_bwp_rrc = 5; + std::string assert_message = + fmt::format("The number of RRC configured DL BWP {} is out of range [0..4].", config.nof_dl_bwp_rrc); test_validator(config, assert_message); } @@ -310,36 +298,32 @@ TEST_F(DciValidatorNonFallbackFixture, BadNofTimeDomainResources) { dci_size_config config = get_base_dci_config(); config.nof_ul_time_domain_res = 17; - std::string assert_message = fmt::format( - R"(The number of UL time domain resource allocations\, i\.e\.\, {} must be within the range \[1\, 16\]\.)", - config.nof_ul_time_domain_res); + std::string assert_message = fmt::format("The number of UL time domain resources {} is out of range [1..16].", + config.nof_ul_time_domain_res); test_validator(config, assert_message); } { dci_size_config config = get_base_dci_config(); config.nof_ul_time_domain_res = 0; - std::string assert_message = fmt::format( - R"(The number of UL time domain resource allocations\, i\.e\.\, {} must be within the range \[1\, 16\]\.)", - config.nof_ul_time_domain_res); + std::string assert_message = fmt::format("The number of UL time domain resources {} is out of range [1..16].", + config.nof_ul_time_domain_res); test_validator(config, assert_message); } { dci_size_config config = get_base_dci_config(); config.nof_dl_time_domain_res = 17; - std::string assert_message = fmt::format( - R"(The number of DL time domain resource allocations\, i\.e\.\, {} must be within the range \[1\, 16\]\.)", - config.nof_dl_time_domain_res); + std::string assert_message = fmt::format("The number of DL time domain resources {} is out of range [1..16].", + config.nof_dl_time_domain_res); test_validator(config, assert_message); } { dci_size_config config = get_base_dci_config(); config.nof_dl_time_domain_res = 0; - std::string assert_message = fmt::format( - R"(The number of DL time domain resource allocations\, i\.e\.\, {} must be within the range \[1\, 16\]\.)", - config.nof_dl_time_domain_res); + std::string assert_message = fmt::format("The number of DL time domain resources {} is out of range [1..16].", + config.nof_dl_time_domain_res); test_validator(config, assert_message); } @@ -350,9 +334,8 @@ TEST_F(DciValidatorNonFallbackFixture, BadAperiodicZpCsiResourceSets) { dci_size_config config = get_base_dci_config(); config.nof_aperiodic_zp_csi = 4; - std::string assert_message = - fmt::format(R"(The number of aperiodic ZP CSI-RS resource sets, i.e., {}, cannot be larger than 3.)", - config.nof_aperiodic_zp_csi); + std::string assert_message = fmt::format("The number of aperiodic ZP-CSI resource sets {} is out of range [0..3].", + config.nof_aperiodic_zp_csi); test_validator(config, assert_message); } @@ -363,7 +346,7 @@ TEST_F(DciValidatorNonFallbackFixture, BadReportTriggerSize) dci_size_config config = get_base_dci_config(); config.report_trigger_size = 7; std::string assert_message = - fmt::format(R"(The report trigger size\, i\.e\.\, {}\, cannot be larger than 6\.)", config.report_trigger_size); + fmt::format("CSI report trigger size {} is out of range [0..6].", config.report_trigger_size); test_validator(config, assert_message); } @@ -374,18 +357,16 @@ TEST_F(DciValidatorNonFallbackFixture, BadNumberOfDonwlinkAckTimings) { dci_size_config config = get_base_dci_config(); config.nof_pdsch_ack_timings = 9; - std::string assert_message = - fmt::format(R"(The number of PDSCH HARQ-ACK timings\, i\.e\.\, {}\, must be within the range \[1\, 8\]\.)", - config.nof_pdsch_ack_timings); + std::string assert_message = fmt::format( + "The number of HARQ-ACK feedback timing entries {} is out of range [1..8].", config.nof_pdsch_ack_timings); test_validator(config, assert_message); } { dci_size_config config = get_base_dci_config(); config.nof_pdsch_ack_timings = 0; - std::string assert_message = - fmt::format(R"(The number of PDSCH HARQ-ACK timings\, i\.e\.\, {}\, must be within the range \[1, 8\]\.)", - config.nof_pdsch_ack_timings); + std::string assert_message = fmt::format( + "The number of HARQ-ACK feedback timing entries {} is out of range [1..8].", config.nof_pdsch_ack_timings); test_validator(config, assert_message); } @@ -395,18 +376,18 @@ TEST_F(DciValidatorNonFallbackFixture, BadNumberOfDonwlinkAckTimings) TEST_F(DciValidatorNonFallbackFixture, BadNumberOfCodeBlockGroupsPerTransportBlock) { { - dci_size_config config = get_base_dci_config(); - config.max_cbg_tb_pusch = 1; - std::string assert_message = fmt::format( - R"(Invalid Maximum CBG per PUSCH TB\, i\.e\.\, {}\. Valid options\: 2\, 4\, 6\, 8\.)", config.max_cbg_tb_pusch); + dci_size_config config = get_base_dci_config(); + config.max_cbg_tb_pusch = 1; + std::string assert_message = + fmt::format("The maximum CBG per PUSCH TB {} is neither 2, 4, 6, nor 8.", config.max_cbg_tb_pusch); test_validator(config, assert_message); } { - dci_size_config config = get_base_dci_config(); - config.max_cbg_tb_pdsch = 1; - std::string assert_message = fmt::format( - R"(Invalid Maximum CBG per PDSCH TB\, i\.e\.\, {}\. Valid options\: 2\, 4\, 6\, 8\.)", config.max_cbg_tb_pdsch); + dci_size_config config = get_base_dci_config(); + config.max_cbg_tb_pdsch = 1; + std::string assert_message = + fmt::format("The maximum CBG per PDSCH TB {} is neither 2, 4, 6, nor 8.", config.max_cbg_tb_pdsch); test_validator(config, assert_message); } @@ -419,8 +400,7 @@ TEST_F(DciValidatorNonFallbackFixture, TransformPrecodingInvalidConfig) dci_size_config config = get_base_dci_config(); config.transform_precoding_enabled = true; config.pusch_dmrs_A_type = dmrs_config_type::type2; - std::string assert_message = - fmt::format(R"(UL DM-RS configuration type 2 cannot be used with transform precoding\.)"); + std::string assert_message = fmt::format("PUSCH DM-RS (A) Type2 is not supported with transform precoding."); test_validator(config, assert_message); } @@ -428,8 +408,7 @@ TEST_F(DciValidatorNonFallbackFixture, TransformPrecodingInvalidConfig) dci_size_config config = get_base_dci_config(); config.transform_precoding_enabled = true; config.pusch_dmrs_B_type = dmrs_config_type::type2; - std::string assert_message = - fmt::format(R"(UL DM-RS configuration type 2 cannot be used with transform precoding\.)"); + std::string assert_message = fmt::format("PUSCH DM-RS (B) Type2 is not supported with transform precoding."); test_validator(config, assert_message); } @@ -442,7 +421,7 @@ TEST_F(DciValidatorNonFallbackFixture, DynamicPdschHarqAckCodebookInvalidConfig) config.pdsch_harq_ack_cb = pdsch_harq_ack_codebook::dynamic; config.dynamic_dual_harq_ack_cb.reset(); std::string assert_message = - fmt::format(R"(Dynamic dual HARQ-ACK codebook flag is required for dynamic PDSCH HARQ-ACK codebook\.)"); + fmt::format("Dynamic dual HARQ-ACK codebook flag is required for dynamic PDSCH HARQ-ACK codebook."); test_validator(config, assert_message); } @@ -454,7 +433,7 @@ TEST_F(DciValidatorNonFallbackFixture, ResourceAllocationTypeZeroInvalidConfig) dci_size_config config = get_base_dci_config(); config.pusch_res_allocation_type = resource_allocation::resource_allocation_type_0; config.nof_ul_rb_groups.reset(); - std::string assert_message = fmt::format(R"(The number of UL RBGs is required for resource allocation type 0\.)"); + std::string assert_message = fmt::format("The number of UL RBGs is required for resource allocation type 0."); test_validator(config, assert_message); } @@ -463,9 +442,7 @@ TEST_F(DciValidatorNonFallbackFixture, ResourceAllocationTypeZeroInvalidConfig) config.pusch_res_allocation_type = resource_allocation::resource_allocation_type_0; config.nof_ul_rb_groups = MAX_NOF_RBGS + 1; std::string assert_message = - fmt::format(R"(The number of UL RBGs\, i\.e\.\, {}\, must be within the range \[1\, {}\]\.)", - config.nof_ul_rb_groups.value(), - MAX_NOF_RBGS); + fmt::format("The number of UL RBGs {} is out of range [1..{}].", config.nof_ul_rb_groups.value(), MAX_NOF_RBGS); test_validator(config, assert_message); } @@ -474,9 +451,7 @@ TEST_F(DciValidatorNonFallbackFixture, ResourceAllocationTypeZeroInvalidConfig) config.pusch_res_allocation_type = resource_allocation::resource_allocation_type_0; config.nof_ul_rb_groups = 0; std::string assert_message = - fmt::format(R"(The number of UL RBGs\, i\.e\.\, {}\, must be within the range \[1\, {}\]\.)", - config.nof_ul_rb_groups.value(), - MAX_NOF_RBGS); + fmt::format("The number of UL RBGs {} is out of range [1..{}].", config.nof_ul_rb_groups.value(), MAX_NOF_RBGS); test_validator(config, assert_message); } @@ -484,7 +459,7 @@ TEST_F(DciValidatorNonFallbackFixture, ResourceAllocationTypeZeroInvalidConfig) dci_size_config config = get_base_dci_config(); config.pdsch_res_allocation_type = resource_allocation::resource_allocation_type_0; config.nof_dl_rb_groups.reset(); - std::string assert_message = fmt::format(R"(The number of DL RBGs is required for resource allocation type 0\.)"); + std::string assert_message = fmt::format("The number of DL RBGs is required for resource allocation type 0."); test_validator(config, assert_message); } @@ -493,9 +468,7 @@ TEST_F(DciValidatorNonFallbackFixture, ResourceAllocationTypeZeroInvalidConfig) config.pdsch_res_allocation_type = resource_allocation::resource_allocation_type_0; config.nof_dl_rb_groups = MAX_NOF_RBGS + 1; std::string assert_message = - fmt::format(R"(The number of DL RBGs\, i\.e\.\, {}\, must be within the range \[1\, {}\]\.)", - config.nof_dl_rb_groups.value(), - MAX_NOF_RBGS); + fmt::format("The number of DL RBGs {} is out of range [1..{}].", config.nof_dl_rb_groups.value(), MAX_NOF_RBGS); test_validator(config, assert_message); } @@ -504,9 +477,7 @@ TEST_F(DciValidatorNonFallbackFixture, ResourceAllocationTypeZeroInvalidConfig) config.pdsch_res_allocation_type = resource_allocation::resource_allocation_type_0; config.nof_dl_rb_groups = 0; std::string assert_message = - fmt::format(R"(The number of DL RBGs\, i\.e\.\, {}\, must be within the range \[1\, {}\]\.)", - config.nof_dl_rb_groups.value(), - MAX_NOF_RBGS); + fmt::format("The number of DL RBGs {} is out of range [1..{}].", config.nof_dl_rb_groups.value(), MAX_NOF_RBGS); test_validator(config, assert_message); } @@ -519,7 +490,7 @@ TEST_F(DciValidatorNonFallbackFixture, ResourceAllocationTypeOneInvalidConfig) config.pdsch_res_allocation_type = resource_allocation::resource_allocation_type_1; config.interleaved_vrb_prb_mapping.reset(); std::string assert_message = - fmt::format(R"(Interleaved VRB to PRB mapping flag is required for PDSCH resource allocation type 1\.)"); + fmt::format("Interleaved VRB to PRB mapping flag is required for PDSCH resource allocation type 1."); test_validator(config, assert_message); } @@ -532,7 +503,7 @@ TEST_F(DciValidatorNonFallbackFixture, NonCodebookTransmissionInvalidConfig) config.tx_config_non_codebook = true; config.pusch_max_layers.reset(); std::string assert_message = - fmt::format(R"(Maximum number of PUSCH layers is required for non-codebook transmission\.)"); + fmt::format("Maximum number of PUSCH layers is required for non-codebook transmission."); test_validator(config, assert_message); } @@ -541,8 +512,7 @@ TEST_F(DciValidatorNonFallbackFixture, NonCodebookTransmissionInvalidConfig) config.tx_config_non_codebook = true; config.pusch_max_layers = 5; std::string assert_message = - fmt::format(R"(Maximum number of PUSH layers\, i\.e\.\, {}\, must be within the valid range \[1\, 4\]\.)", - config.pusch_max_layers.value()); + fmt::format("Maximum number of PUSCH layers {} is out of range [1..4].", config.pusch_max_layers.value()); test_validator(config, assert_message); } @@ -551,8 +521,7 @@ TEST_F(DciValidatorNonFallbackFixture, NonCodebookTransmissionInvalidConfig) config.tx_config_non_codebook = true; config.pusch_max_layers = 0; std::string assert_message = - fmt::format(R"(Maximum number of PUSH layers\, i\.e\.\, {}\, must be within the valid range \[1\, 4\]\.)", - config.pusch_max_layers.value()); + fmt::format("Maximum number of PUSCH layers {} is out of range [1..4].", config.pusch_max_layers.value()); test_validator(config, assert_message); } @@ -560,18 +529,18 @@ TEST_F(DciValidatorNonFallbackFixture, NonCodebookTransmissionInvalidConfig) dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = true; config.nof_srs_resources = 5; - std::string assert_message = fmt::format( - R"(Number of SRS resources\, i\.e\.\, {}\, must be within the range \[1\, 4\] for non-codebook transmission\.)", - config.nof_srs_resources); + std::string assert_message = + fmt::format("The number of SRS resources {} is out of range [1..4] for non-codebook transmission.", + config.nof_srs_resources); test_validator(config, assert_message); } { dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = true; config.nof_srs_resources = 0; - std::string assert_message = fmt::format( - R"(Number of SRS resources\, i\.e\.\, {}\, must be within the range \[1\, 4\] for non-codebook transmission\.)", - config.nof_srs_resources); + std::string assert_message = + fmt::format("The number of SRS resources {} is out of range [1..4] for non-codebook transmission.", + config.nof_srs_resources); test_validator(config, assert_message); } } @@ -583,7 +552,7 @@ TEST_F(DciValidatorNonFallbackFixture, NonCodebookTransmissionUnsupportedConfig) dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = true; config.pusch_max_layers = 2; - std::string assert_message = fmt::format(R"(Multiple layers on PUSCH are not currently supported\.)"); + std::string assert_message = fmt::format("Multiple layers on PUSCH are not currently supported."); test_validator(config, assert_message); } } @@ -595,7 +564,7 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = false; config.max_rank.reset(); - std::string assert_message = fmt::format(R"(Maximum rank is required for codebook transmission\.)"); + std::string assert_message = fmt::format("Maximum rank is required for codebook transmission."); test_validator(config, assert_message); } @@ -603,8 +572,7 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = false; config.max_rank = 5; - std::string assert_message = fmt::format( - R"(Maximum rank\, i\.e\.\, {}\, must be within the valid range \[1\, 4\]\.)", config.max_rank.value()); + std::string assert_message = fmt::format("Maximum rank {} is out of range [1..4].", config.max_rank.value()); test_validator(config, assert_message); } @@ -612,8 +580,7 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = false; config.max_rank = 0; - std::string assert_message = fmt::format( - R"(Maximum rank\, i\.e\.\, {}\, must be within the valid range \[1\, 4\]\.)", config.max_rank.value()); + std::string assert_message = fmt::format("Maximum rank {} is out of range [1..4].", config.max_rank.value()); test_validator(config, assert_message); } @@ -622,8 +589,7 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) config.tx_config_non_codebook = false; config.nof_srs_resources = 3; std::string assert_message = fmt::format( - R"(Number of SRS resources\, i\.e\.\, {}\, must be within the range \[1\, 2\] for codebook transmission\.)", - config.nof_srs_resources); + "The number of SRS resources {} is out of range [1..2] for codebook transmission.", config.nof_srs_resources); test_validator(config, assert_message); } @@ -631,7 +597,7 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = false; config.nof_srs_ports.reset(); - std::string assert_message = fmt::format(R"(Number of SRS antenna ports is required for codebook transmission\.)"); + std::string assert_message = fmt::format("Number of SRS ports is required for codebook transmission."); test_validator(config, assert_message); } @@ -639,8 +605,8 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = false; config.nof_srs_ports = 3; - std::string assert_message = fmt::format( - R"(Invalid number of SRS ports\, i\.e\.\, {}\. Valid options\: 1\, 2\, 4\.)", config.nof_srs_ports.value()); + std::string assert_message = + fmt::format("The number of SRS ports {} is neither 1, 2, nor 4.", config.nof_srs_ports.value()); test_validator(config, assert_message); } @@ -649,10 +615,10 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) config.tx_config_non_codebook = false; config.nof_srs_ports = 2; config.max_rank = 3; - std::string assert_message = fmt::format( - R"(Maximum rank\, i\.e\.\, {}\, cannot be larger than the number of SRS antenna ports\, i\.e\.\, {}\.)", - config.max_rank.value(), - config.nof_srs_ports.value()); + std::string assert_message = + fmt::format("Maximum rank {} cannot be larger than the number of SRS antenna ports {}.", + config.max_rank.value(), + config.nof_srs_ports.value()); test_validator(config, assert_message); } @@ -662,32 +628,18 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) config.nof_srs_ports = 2; config.cb_subset.reset(); std::string assert_message = - fmt::format(R"(Codebook subset is required for codebook transmission with multiple antenna ports.)"); + fmt::format("Codebook subset is required for codebook transmission with multiple antenna ports."); test_validator(config, assert_message); } } -// Checks for unsupported DCI configurations with codebook based transmission. -TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionUnsupportedConfig) -{ - dci_size_config config = get_base_dci_config(); - config.tx_config_non_codebook = false; - config.nof_srs_ports = 2; - std::string assert_message = fmt::format(R"(UL precoding is not currently supported\.)"); - - test_validator(config, assert_message); -} - // Checks for unsupported DCI configurations with PT-RS. TEST_F(DciValidatorNonFallbackFixture, PtrsUnsupportedConfig) { - dci_size_config config = get_base_dci_config(); - config.ptrs_uplink_configured = true; - config.transform_precoding_enabled = false; - config.tx_config_non_codebook = true; - std::string assert_message = - fmt::format(R"(PT\-RS with more than one DM\-RS is not currently supported\.)", config.max_cbg_tb_pdsch); + dci_size_config config = get_base_dci_config(); + config.ptrs_uplink_configured = true; + std::string assert_message = "PT-RS is not currently supported."; test_validator(config, assert_message); } @@ -699,8 +651,7 @@ TEST_F(DciValidatorNonFallbackFixture, DmrsConfigurationNotPresent) dci_size_config config = get_base_dci_config(); config.pusch_dmrs_A_type.reset(); config.pusch_dmrs_B_max_len.reset(); - std::string assert_message = - fmt::format(R"(At least one PUSCH DM\-RS mapping \(type A or type B\) must be configured\.)"); + std::string assert_message = fmt::format("At least one PUSCH DM-RS mapping (type A or type B) must be configured."); test_validator(config, assert_message); } @@ -708,8 +659,7 @@ TEST_F(DciValidatorNonFallbackFixture, DmrsConfigurationNotPresent) dci_size_config config = get_base_dci_config(); config.pdsch_dmrs_A_type.reset(); config.pdsch_dmrs_B_max_len.reset(); - std::string assert_message = - fmt::format(R"(At least one PDSCH DM\-RS mapping \(type A or type B\) must be configured\.)"); + std::string assert_message = fmt::format("At least one PDSCH DM-RS mapping (type A or type B) must be configured."); test_validator(config, assert_message); } From c97794e7828a7fb07a638dc1640a44369ceaa1dc Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 23 Sep 2024 14:35:44 +0200 Subject: [PATCH 120/174] ran: review DCI size config validation related --- lib/ran/pdcch/dci_packing.cpp | 14 ++++++++++--- lib/scheduler/config/ue_configuration.cpp | 24 ++++++++++++++++------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/ran/pdcch/dci_packing.cpp b/lib/ran/pdcch/dci_packing.cpp index 35dceb4fc5..ca0fcf1a05 100644 --- a/lib/ran/pdcch/dci_packing.cpp +++ b/lib/ran/pdcch/dci_packing.cpp @@ -503,10 +503,18 @@ static dci_1_1_size dci_f1_1_bits_before_padding(const dci_size_config& dci_conf return sizes; } -static void assert_dci_size_config(const dci_size_config& config) +static void assert_dci_size_config(const dci_size_config& dci_sz_cfg) { - error_type error = validate_dci_size_config(config); - srsran_assert(error.has_value(), "Invalid DCI size configuration: {}", error.error()); + [[maybe_unused]] std::string error_msg; + [[maybe_unused]] auto validate_dci_sz_cfg = [&dci_sz_cfg, &error_msg]() { + error_type dci_size_valid = validate_dci_size_config(dci_sz_cfg); + bool is_success = dci_size_valid.has_value(); + if (!is_success) { + error_msg = dci_size_valid.error(); + } + return is_success; + }; + srsran_assert(validate_dci_sz_cfg(), "Invalid DCI size configuration: {}", error_msg); } dci_sizes srsran::get_dci_sizes(const dci_size_config& config) diff --git a/lib/scheduler/config/ue_configuration.cpp b/lib/scheduler/config/ue_configuration.cpp index 13bcd1395e..c2e5c66e5e 100644 --- a/lib/scheduler/config/ue_configuration.cpp +++ b/lib/scheduler/config/ue_configuration.cpp @@ -568,6 +568,20 @@ static void generate_crnti_monitored_pdcch_candidates(bwp_info& bwp_cfg, rnti_t //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static void assert_dci_size_config(search_space_id ss_id, const dci_size_config& dci_sz_cfg) +{ + [[maybe_unused]] std::string error_msg; + [[maybe_unused]] auto validate_dci_sz_cfg = [&dci_sz_cfg, &error_msg]() { + error_type dci_size_valid = validate_dci_size_config(dci_sz_cfg); + bool is_success = dci_size_valid.has_value(); + if (!is_success) { + error_msg = dci_size_valid.error(); + } + return is_success; + }; + srsran_assert(validate_dci_sz_cfg(), "Invalid DCI size configuration for SearchSpace={}: {}", ss_id, error_msg); +} + ue_cell_configuration::ue_cell_configuration(rnti_t crnti_, const cell_configuration& cell_cfg_common_, const serving_cell_config& serv_cell_cfg_, @@ -619,17 +633,13 @@ void ue_cell_configuration::reconfigure(const serving_cell_config& cell_cfg_ded_ // Compute DCI sizes for (search_space_info& ss : search_spaces) { + // Generate DCI size calculation parameters. ss.dci_sz_cfg = get_dci_size_config(*this, multi_cells_configured, ss.cfg->get_id()); // Verify the DCI size configuration is valid. - const error_type dci_size_valid = validate_dci_size_config(ss.dci_sz_cfg); - if (!dci_size_valid.has_value()) { - srsran_assert(!dci_size_valid.has_value(), - "Invalid DCI size configuration for SearchSpace={}: {}", - ss.cfg->get_id(), - dci_size_valid.error()); - } + assert_dci_size_config(ss.cfg->get_id(), ss.dci_sz_cfg); + // Calculate DCI sizes. ss.dci_sz = get_dci_sizes(ss.dci_sz_cfg); } From 215af553517b32d6ad4e97f082dfd11744266a27 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Wed, 18 Sep 2024 11:31:09 +0200 Subject: [PATCH 121/174] flexible_du: add split 7.2 du implementation worker_manager: removed the dependency of the manager with the configurations of the application unit. Added a configuration for the worker manager and translators to fill it from the app unit configs. --- CMakeLists.txt | 4 +- apps/du/CMakeLists.txt | 2 +- apps/du/du.cpp | 47 ++-- apps/du/du_appconfig_translators.cpp | 8 + apps/du/du_appconfig_translators.h | 4 + apps/gnb/CMakeLists.txt | 2 +- apps/gnb/gnb.cpp | 66 ++--- apps/gnb/gnb_appconfig_translators.cpp | 7 + apps/gnb/gnb_appconfig_translators.h | 10 +- apps/services/worker_manager.cpp | 262 +++++++---------- apps/services/worker_manager.h | 40 +-- apps/services/worker_manager_config.h | 108 +++++++ apps/units/application_unit.h | 6 +- .../cu_cp/cu_cp_application_unit_impl.cpp | 2 +- .../units/cu_cp/cu_cp_application_unit_impl.h | 2 +- apps/units/cu_cp/cu_cp_config_translators.cpp | 15 + apps/units/cu_cp/cu_cp_config_translators.h | 4 + .../cu_up/cu_up_application_unit_impl.cpp | 2 +- .../units/cu_up/cu_up_application_unit_impl.h | 2 +- .../cu_up/cu_up_unit_config_translators.cpp | 17 ++ .../cu_up/cu_up_unit_config_translators.h | 4 + .../flexible_du/du_high/du_high_config.h | 3 + .../du_high/du_high_config_translators.cpp | 33 +++ .../du_high/du_high_config_translators.h | 6 + .../du_low/du_low_config_cli11_schema.cpp | 4 +- .../du_low/du_low_config_cli11_schema.h | 2 +- .../du_low/du_low_config_translator.cpp | 24 ++ .../du_low/du_low_config_translator.h | 7 + .../du_low/du_low_wrapper_config_helper.cpp | 2 + apps/units/flexible_du/fapi/CMakeLists.txt | 1 + .../fapi/fapi_config_translator.cpp | 28 ++ .../flexible_du/fapi/fapi_config_translator.h | 23 ++ .../flexible_du_application_unit.h | 48 ++++ .../split6_du_application_unit_impl.cpp | 31 ++- .../split_6/split6_du_application_unit_impl.h | 24 +- .../flexible_du/split_7_2/CMakeLists.txt | 44 ++- .../split_7_2/helpers/CMakeLists.txt | 22 ++ .../split_7_2/{ => helpers}/ru_ofh_config.h | 0 .../ru_ofh_config_cli11_schema.cpp | 0 .../ru_ofh_config_cli11_schema.h | 0 .../ru_ofh_config_translator.cpp | 29 ++ .../{ => helpers}/ru_ofh_config_translator.h | 6 + .../{ => helpers}/ru_ofh_config_validator.cpp | 0 .../{ => helpers}/ru_ofh_config_validator.h | 0 .../ru_ofh_config_yaml_writer.cpp | 0 .../{ => helpers}/ru_ofh_config_yaml_writer.h | 0 .../{ => helpers}/ru_ofh_factories.cpp | 0 .../{ => helpers}/ru_ofh_factories.h | 0 .../{ => helpers}/ru_ofh_logger_registrator.h | 0 .../split_7_2_du_application_unit_impl.cpp | 70 +++++ .../split_7_2_du_application_unit_impl.h | 51 ++++ .../split_7_2/split_7_2_du_factory.cpp | 263 ++++++++++++++++++ .../split_7_2/split_7_2_du_factory.h | 41 +++ .../split_7_2/split_7_2_du_impl.cpp | 67 +++++ .../flexible_du/split_7_2/split_7_2_du_impl.h | 62 +++++ .../split_7_2_du_unit_cli11_schema.cpp | 46 +++ .../split_7_2_du_unit_cli11_schema.h | 25 ++ .../split_7_2/split_7_2_du_unit_config.h | 32 +++ .../split_7_2_du_unit_config_validator.cpp | 84 ++++++ .../split_7_2_du_unit_config_validator.h | 21 ++ .../split_7_2_du_unit_config_yaml_writer.cpp | 26 ++ .../split_7_2_du_unit_config_yaml_writer.h | 22 ++ .../split_7_2_du_unit_logger_registrator.h | 30 ++ .../split_8/ru_sdr_config_translator.cpp | 19 ++ .../split_8/ru_sdr_config_translator.h | 5 + .../flexible_du/split_dynamic/CMakeLists.txt | 10 +- .../dynamic_du_application_unit_impl.cpp | 34 ++- .../dynamic_du_application_unit_impl.h | 22 +- .../split_dynamic/dynamic_du_factory.cpp | 14 +- .../split_dynamic/dynamic_du_factory.h | 14 +- .../split_dynamic/dynamic_du_translators.cpp | 43 +++ .../split_dynamic/dynamic_du_translators.h | 5 + .../dynamic_du_unit_cli11_schema.cpp | 2 +- .../split_dynamic/dynamic_du_unit_config.h | 2 +- .../dynamic_du_unit_config_validator.cpp | 2 +- .../dynamic_du_unit_config_yaml_writer.cpp | 2 +- .../dynamic_du_unit_logger_registrator.h | 2 +- 77 files changed, 1651 insertions(+), 316 deletions(-) create mode 100644 apps/services/worker_manager_config.h create mode 100644 apps/units/flexible_du/fapi/fapi_config_translator.cpp create mode 100644 apps/units/flexible_du/fapi/fapi_config_translator.h create mode 100644 apps/units/flexible_du/flexible_du_application_unit.h create mode 100644 apps/units/flexible_du/split_7_2/helpers/CMakeLists.txt rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config.h (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_cli11_schema.cpp (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_cli11_schema.h (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_translator.cpp (85%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_translator.h (69%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_validator.cpp (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_validator.h (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_yaml_writer.cpp (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_config_yaml_writer.h (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_factories.cpp (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_factories.h (100%) rename apps/units/flexible_du/split_7_2/{ => helpers}/ru_ofh_logger_registrator.h (100%) create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.cpp create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.h create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_factory.cpp create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_factory.h create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_impl.cpp create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_impl.h create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.cpp create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.h create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_config.h create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.cpp create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.h create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.cpp create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.h create mode 100644 apps/units/flexible_du/split_7_2/split_7_2_du_unit_logger_registrator.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1042911ba2..08dc714aaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -349,7 +349,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${MARCH} -mtune=${MTUNE}") # DU split setup ######################################################################## # Public variable to select the DU split. -set(DU_SPLIT_TYPE "DYNAMIC" CACHE STRING "DU split type. Default value is 'DYNAMIC'. Allowed values: DYNAMIC, SPLIT_6") +set(DU_SPLIT_TYPE "DYNAMIC" CACHE STRING "DU split type. Default value is 'DYNAMIC'. Allowed values: DYNAMIC, SPLIT_6, SPLIT_7_2") # Internal private booleans to represent the selected DU split type. Values auto-derived from DU_SPLIT_TYPE variable. set(DU_SPLIT_DYNAMIC OFF CACHE BOOL "DU dynamic split enabled boolean") @@ -361,6 +361,8 @@ if (DU_SPLIT_TYPE STREQUAL "DYNAMIC") set(DU_SPLIT_DYNAMIC ON) elseif (DU_SPLIT_TYPE STREQUAL "SPLIT_6") set(DU_SPLIT_6 ON) +elseif (DU_SPLIT_TYPE STREQUAL "SPLIT_7_2") + set(DU_SPLIT_7_2 ON) else () message(WARNING "DU split value '${DU_SPLIT_TYPE}' is not supported. Defaulting to 'DYNAMIC'") set(DU_SPLIT_TYPE "DYNAMIC") diff --git a/apps/du/CMakeLists.txt b/apps/du/CMakeLists.txt index 4b83471e2e..00f54255f8 100644 --- a/apps/du/CMakeLists.txt +++ b/apps/du/CMakeLists.txt @@ -28,7 +28,7 @@ target_link_libraries(srsdu srsran_pcap srsran_support srsran_versioning - srsran_flexible_du_dynamic + srsran_flexible_du srsran_f1c_gateway srsran_cu_up # TODO: Delete ) diff --git a/apps/du/du.cpp b/apps/du/du.cpp index dd9c189b24..cebba0811a 100644 --- a/apps/du/du.cpp +++ b/apps/du/du.cpp @@ -50,11 +50,9 @@ #include "apps/services/metrics/metrics_manager.h" #include "apps/services/metrics/metrics_notifier_proxy.h" #include "apps/services/stdin_command_dispatcher.h" +#include "apps/units/flexible_du/du_high/du_high_config.h" #include "apps/units/flexible_du/du_high/pcap_factory.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h" +#include "apps/units/flexible_du/flexible_du_application_unit.h" #include "srsran/du/du_power_controller.h" @@ -110,7 +108,7 @@ static void initialize_log(const std::string& filename) srslog::init(); } -static void register_app_logs(const logger_appconfig& log_cfg, const dynamic_du_unit_config& du_loggers) +static void register_app_logs(const logger_appconfig& log_cfg, flexible_du_application_unit& du_app_unit) { // Set log-level of app and all non-layer specific components to app level. for (const auto& id : {"ALL", "SCTP-GW", "IO-EPOLL", "UDP-GW", "PCAP"}) { @@ -138,7 +136,7 @@ static void register_app_logs(const logger_appconfig& log_cfg, const dynamic_du_ e2ap_logger.set_hex_dump_max_size(log_cfg.hex_max_size); // Register units logs. - register_dynamic_du_loggers(du_loggers); + du_app_unit.on_loggers_registration(); } int main(int argc, char** argv) @@ -167,14 +165,14 @@ int main(int argc, char** argv) // Configure CLI11 with the DU application configuration schema. configure_cli11_with_du_appconfig_schema(app, du_cfg); - dynamic_du_unit_config du_unit_cfg; - du_unit_cfg.du_high_cfg.config.pcaps.set_default_filename("/tmp/du"); - configure_cli11_with_dynamic_du_unit_config_schema(app, du_unit_cfg); + auto du_app_unit = create_flexible_du_application_unit(); + du_app_unit->get_du_high_unit_config().pcaps.set_default_filename("/tmp/du"); + du_app_unit->on_parsing_configuration_registration(app); // Set the callback for the app calling all the autoderivation functions. - app.callback([&app, &du_cfg, &du_unit_cfg]() { + app.callback([&app, &du_cfg, &du_app_unit]() { autoderive_du_parameters_after_parsing(app, du_cfg); - autoderive_dynamic_du_parameters_after_parsing(app, du_unit_cfg); + du_app_unit->on_configuration_parameters_autoderivation(app); }); // Parse arguments. @@ -182,23 +180,22 @@ int main(int argc, char** argv) // Check the modified configuration. if (!validate_appconfig(du_cfg) || - !validate_dynamic_du_unit_config(du_unit_cfg, - (du_cfg.expert_execution_cfg.affinities.isolated_cpus) - ? du_cfg.expert_execution_cfg.affinities.isolated_cpus.value() - : os_sched_affinity_bitmask::available_cpus())) { + !du_app_unit->on_configuration_validation((du_cfg.expert_execution_cfg.affinities.isolated_cpus) + ? du_cfg.expert_execution_cfg.affinities.isolated_cpus.value() + : os_sched_affinity_bitmask::available_cpus())) { report_error("Invalid configuration detected.\n"); } // Set up logging. initialize_log(du_cfg.log_cfg.filename); - register_app_logs(du_cfg.log_cfg, du_unit_cfg); + register_app_logs(du_cfg.log_cfg, *du_app_unit); // Log input configuration. srslog::basic_logger& config_logger = srslog::fetch_basic_logger("CONFIG"); if (config_logger.debug.enabled()) { YAML::Node node; fill_du_appconfig_in_yaml_schema(node, du_cfg); - fill_dynamic_du_unit_config_in_yaml_schema(node, du_unit_cfg); + du_app_unit->dump_config(node); config_logger.debug("Input configuration (all values): \n{}", YAML::Dump(node)); } else { config_logger.info("Input configuration (only non-default values): \n{}", app.config_to_str(false, false)); @@ -247,10 +244,12 @@ int main(int argc, char** argv) check_cpu_governor(du_logger); check_drm_kms_polling(du_logger); - cu_cp_unit_pcap_config dummy_cu_cp_pcap{}; - cu_up_unit_pcap_config dummy_cu_up_pcap{}; - worker_manager workers{ - du_unit_cfg, du_cfg.expert_execution_cfg, dummy_cu_cp_pcap, dummy_cu_up_pcap, du_cfg.nru_cfg.pdu_queue_size}; + // Instantiate worker manager. + worker_manager_config worker_manager_cfg; + fill_du_worker_manager_config(worker_manager_cfg, du_cfg); + du_app_unit->fill_worker_manager_config(worker_manager_cfg); + + worker_manager workers{worker_manager_cfg}; // Set layer-specific pcap options. const auto& low_prio_cpu_mask = du_cfg.expert_execution_cfg.affinities.low_priority_cpu_cfg.mask; @@ -260,7 +259,7 @@ int main(int argc, char** argv) std::unique_ptr epoll_broker = create_io_broker(io_broker_type::epoll, io_broker_cfg); srsran::modules::flexible_du::du_pcaps du_pcaps = - modules::flexible_du::create_pcaps(du_unit_cfg.du_high_cfg.config.pcaps, workers); + modules::flexible_du::create_pcaps(du_app_unit->get_du_high_unit_config().pcaps, workers); // Instantiate F1-C client gateway. std::unique_ptr f1c_gw = create_f1c_client_gateway( @@ -291,7 +290,7 @@ int main(int argc, char** argv) srslog::sink& json_sink = srslog::fetch_udp_sink(du_cfg.metrics_cfg.addr, du_cfg.metrics_cfg.port, srslog::create_json_formatter()); - e2_metric_connector_manager e2_metric_connectors(du_unit_cfg.du_high_cfg.config.cells_cfg.size()); + e2_metric_connector_manager e2_metric_connectors(du_app_unit->get_du_high_unit_config().cells_cfg.size()); // E2AP configuration. srsran::sctp_network_connector_config e2_du_nw_config = generate_e2ap_nw_config(du_cfg, E2_DU_PPID); @@ -312,7 +311,7 @@ int main(int argc, char** argv) du_dependencies.json_sink = &json_sink; du_dependencies.metrics_notifier = &metrics_notifier_forwarder; - auto du_inst_and_cmds = create_du(du_unit_cfg, du_dependencies); + auto du_inst_and_cmds = du_app_unit->create_flexible_du_unit(du_dependencies); // Only DU has metrics now. app_services::metrics_manager metrics_mngr( diff --git a/apps/du/du_appconfig_translators.cpp b/apps/du/du_appconfig_translators.cpp index 2428494ce5..9f16690ac9 100644 --- a/apps/du/du_appconfig_translators.cpp +++ b/apps/du/du_appconfig_translators.cpp @@ -9,6 +9,7 @@ */ #include "du_appconfig_translators.h" +#include "apps/services/worker_manager_config.h" #include "du_appconfig.h" using namespace srsran; @@ -43,3 +44,10 @@ srsran::sctp_network_connector_config srsran::generate_e2ap_nw_config(const du_a return out_cfg; } + +void srsran::fill_du_worker_manager_config(worker_manager_config& config, const du_appconfig& unit_cfg) +{ + config.gtpu_queue_size = unit_cfg.nru_cfg.pdu_queue_size; + config.nof_low_prio_threads = unit_cfg.expert_execution_cfg.threads.non_rt_threads.nof_non_rt_threads; + config.low_prio_sched_config = unit_cfg.expert_execution_cfg.affinities.low_priority_cpu_cfg; +} diff --git a/apps/du/du_appconfig_translators.h b/apps/du/du_appconfig_translators.h index f81b39dd8e..52653fd17e 100644 --- a/apps/du/du_appconfig_translators.h +++ b/apps/du/du_appconfig_translators.h @@ -16,8 +16,12 @@ namespace srsran { struct du_appconfig; +struct worker_manager_config; /// Converts and returns the given gnb application configuration to a E2AP Network Gateway configuration. sctp_network_connector_config generate_e2ap_nw_config(const du_appconfig& config, int ppid); +/// Fills the DU worker manager parameters of the given worker manager configuration. +void fill_du_worker_manager_config(worker_manager_config& config, const du_appconfig& unit_cfg); + } // namespace srsran \ No newline at end of file diff --git a/apps/gnb/CMakeLists.txt b/apps/gnb/CMakeLists.txt index 8c526dc122..1cfb7444e0 100644 --- a/apps/gnb/CMakeLists.txt +++ b/apps/gnb/CMakeLists.txt @@ -31,7 +31,7 @@ target_link_libraries(gnb srsran_pcap srsran_support srsran_versioning - srsran_flexible_du_dynamic + srsran_flexible_du srsran_f1c_gateway srsran_e1_gateway srsran_cu_cp_app_unit diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 1ae40077a0..bbb60d487e 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -65,13 +65,13 @@ #include "apps/units/cu_cp/cu_cp_unit_config_yaml_writer.h" #include "apps/units/cu_cp/pcap_factory.h" #include "apps/units/cu_up/cu_up_builder.h" +#include "apps/units/cu_up/cu_up_unit_config_translators.h" #include "apps/units/cu_up/cu_up_unit_config_yaml_writer.h" #include "apps/units/cu_up/pcap_factory.h" +#include "apps/units/flexible_du/du_high/du_high_config.h" #include "apps/units/flexible_du/du_high/pcap_factory.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.h" -#include "apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h" +#include "apps/units/flexible_du/flexible_du_application_unit.h" + #include "srsran/du/du_power_controller.h" #include "srsran/support/cli11_utils.h" @@ -137,7 +137,7 @@ static void initialize_log(const std::string& filename) static void register_app_logs(const logger_appconfig& log_cfg, const cu_cp_unit_logger_config& cu_cp_loggers, const cu_up_unit_logger_config& cu_up_loggers, - const dynamic_du_unit_config& du_loggers) + flexible_du_application_unit& du_app_unit) { // Set log-level of app and all non-layer specific components to app level. for (const auto& id : {"ALL", "SCTP-GW", "IO-EPOLL", "UDP-GW", "PCAP"}) { @@ -167,13 +167,13 @@ static void register_app_logs(const logger_appconfig& log_cfg, // Register units logs. register_cu_cp_loggers(cu_cp_loggers); register_cu_up_loggers(cu_up_loggers); - register_dynamic_du_loggers(du_loggers); + du_app_unit.on_loggers_registration(); } -static void autoderive_slicing_args(dynamic_du_unit_config& du_unit_cfg, cu_cp_unit_config& cu_cp_config) +static void autoderive_slicing_args(du_high_unit_config& du_hi_cfg, cu_cp_unit_config& cu_cp_config) { std::vector du_slices; - for (const auto& cell_cfg : du_unit_cfg.du_high_cfg.config.cells_cfg) { + for (const auto& cell_cfg : du_hi_cfg.cells_cfg) { for (const auto& slice : cell_cfg.cell.slice_cfg) { if (du_slices.end() == std::find(du_slices.begin(), du_slices.end(), slice.s_nssai)) { du_slices.push_back(slice.s_nssai); @@ -224,18 +224,18 @@ int main(int argc, char** argv) cu_up_config.pcap_cfg.set_default_filename("/tmp/gnb"); configure_cli11_with_cu_up_unit_config_schema(app, cu_up_config); - dynamic_du_unit_config du_unit_cfg; - du_unit_cfg.du_high_cfg.config.pcaps.set_default_filename("/tmp/gnb"); - configure_cli11_with_dynamic_du_unit_config_schema(app, du_unit_cfg); + auto du_app_unit = create_flexible_du_application_unit(); + du_app_unit->get_du_high_unit_config().pcaps.set_default_filename("/tmp/gnb"); + du_app_unit->on_parsing_configuration_registration(app); // Set the callback for the app calling all the autoderivation functions. - app.callback([&app, &gnb_cfg, &du_unit_cfg, &cu_cp_config, &cu_up_config]() { + app.callback([&app, &gnb_cfg, &du_app_unit, &cu_cp_config, &cu_up_config]() { autoderive_gnb_parameters_after_parsing(app, gnb_cfg); - autoderive_slicing_args(du_unit_cfg, cu_cp_config); - autoderive_dynamic_du_parameters_after_parsing(app, du_unit_cfg); + autoderive_slicing_args(du_app_unit->get_du_high_unit_config(), cu_cp_config); + du_app_unit->on_configuration_parameters_autoderivation(app); // If test mode is enabled, we auto-enable "no_core" option and generate a amf config with no core. - if (du_unit_cfg.du_high_cfg.config.test_mode_cfg.test_ue.rnti != rnti_t::INVALID_RNTI) { + if (du_app_unit->get_du_high_unit_config().is_testmode_enabled()) { cu_cp_config.amf_config.no_core = true; cu_cp_config.amf_config.amf.supported_tas = {{7, {{"00101", {s_nssai_t{1}}}}}}; } @@ -251,17 +251,16 @@ int main(int argc, char** argv) // Check the modified configuration. if (!validate_appconfig(gnb_cfg) || !validate_cu_cp_unit_config(cu_cp_config) || !validate_cu_up_unit_config(cu_up_config) || - !validate_dynamic_du_unit_config(du_unit_cfg, - (gnb_cfg.expert_execution_cfg.affinities.isolated_cpus) - ? gnb_cfg.expert_execution_cfg.affinities.isolated_cpus.value() - : os_sched_affinity_bitmask::available_cpus()) || - !validate_plmn_and_tacs(du_unit_cfg.du_high_cfg.config, cu_cp_config)) { + !du_app_unit->on_configuration_validation((gnb_cfg.expert_execution_cfg.affinities.isolated_cpus) + ? gnb_cfg.expert_execution_cfg.affinities.isolated_cpus.value() + : os_sched_affinity_bitmask::available_cpus()) || + !validate_plmn_and_tacs(du_app_unit->get_du_high_unit_config(), cu_cp_config)) { report_error("Invalid configuration detected.\n"); } // Set up logging. initialize_log(gnb_cfg.log_cfg.filename); - register_app_logs(gnb_cfg.log_cfg, cu_cp_config.loggers, cu_up_config.loggers, du_unit_cfg); + register_app_logs(gnb_cfg.log_cfg, cu_cp_config.loggers, cu_up_config.loggers, *du_app_unit); // Log input configuration. srslog::basic_logger& config_logger = srslog::fetch_basic_logger("CONFIG"); @@ -270,7 +269,7 @@ int main(int argc, char** argv) fill_gnb_appconfig_in_yaml_schema(node, gnb_cfg); fill_cu_up_config_in_yaml_schema(node, cu_up_config); fill_cu_cp_config_in_yaml_schema(node, cu_cp_config); - fill_dynamic_du_unit_config_in_yaml_schema(node, du_unit_cfg); + du_app_unit->dump_config(node); config_logger.debug("Input configuration (all values): \n{}", YAML::Dump(node)); } else { config_logger.info("Input configuration (only non-default values): \n{}", app.config_to_str(false, false)); @@ -319,11 +318,14 @@ int main(int argc, char** argv) check_cpu_governor(gnb_logger); check_drm_kms_polling(gnb_logger); - worker_manager workers{du_unit_cfg, - gnb_cfg.expert_execution_cfg, - cu_cp_config.pcap_cfg, - cu_up_config.pcap_cfg, - cu_up_config.gtpu_queue_size}; + // Instantiate worker manager. + worker_manager_config worker_manager_cfg; + fill_gnb_worker_manager_config(worker_manager_cfg, gnb_cfg); + fill_cu_cp_worker_manager_config(worker_manager_cfg, cu_cp_config); + fill_cu_up_worker_manager_config(worker_manager_cfg, cu_up_config); + du_app_unit->fill_worker_manager_config(worker_manager_cfg); + + worker_manager workers{worker_manager_cfg}; // Set layer-specific pcap options. const auto& low_prio_cpu_mask = gnb_cfg.expert_execution_cfg.affinities.low_priority_cpu_cfg.mask; @@ -336,13 +338,13 @@ int main(int argc, char** argv) // In the gNB app, there is no point in instantiating two pcaps for each node of E1 and F1. // We disable one accordingly. cu_up_config.pcap_cfg.disable_e1_pcaps(); - du_unit_cfg.du_high_cfg.config.pcaps.disable_f1_pcaps(); + du_app_unit->get_du_high_unit_config().pcaps.disable_f1_pcaps(); srsran::modules::cu_cp::cu_cp_dlt_pcaps cu_cp_dlt_pcaps = modules::cu_cp::create_dlt_pcap(cu_cp_config.pcap_cfg, *workers.get_executor_getter()); srsran::modules::cu_up::cu_up_dlt_pcaps cu_up_dlt_pcaps = modules::cu_up::create_dlt_pcaps(cu_up_config.pcap_cfg, *workers.get_executor_getter()); srsran::modules::flexible_du::du_pcaps du_pcaps = - modules::flexible_du::create_pcaps(du_unit_cfg.du_high_cfg.config.pcaps, workers); + modules::flexible_du::create_pcaps(du_app_unit->get_du_high_unit_config().pcaps, workers); std::unique_ptr f1c_gw = create_f1c_local_connector(f1c_local_connector_config{*cu_cp_dlt_pcaps.f1ap}); @@ -353,7 +355,7 @@ int main(int argc, char** argv) timer_manager app_timers{256}; timer_manager* cu_timers = &app_timers; std::unique_ptr dummy_timers; - if (du_unit_cfg.du_high_cfg.config.test_mode_cfg.test_ue.rnti != rnti_t::INVALID_RNTI) { + if (du_app_unit->get_du_high_unit_config().is_testmode_enabled()) { // In case test mode is enabled, we pass dummy timers to the upper layers. dummy_timers = std::make_unique(256); cu_timers = dummy_timers.get(); @@ -366,7 +368,7 @@ int main(int argc, char** argv) srslog::sink& json_sink = srslog::fetch_udp_sink(gnb_cfg.metrics_cfg.addr, gnb_cfg.metrics_cfg.port, srslog::create_json_formatter()); - e2_metric_connector_manager e2_metric_connectors(du_unit_cfg.du_high_cfg.config.cells_cfg.size()); + e2_metric_connector_manager e2_metric_connectors(du_app_unit->get_du_high_unit_config().cells_cfg.size()); // Create CU-CP config. cu_cp_build_dependencies cu_cp_dependencies; @@ -452,7 +454,7 @@ int main(int argc, char** argv) du_dependencies.json_sink = &json_sink; du_dependencies.metrics_notifier = &metrics_notifier_forwarder; - auto du_inst_and_cmds = create_du(du_unit_cfg, du_dependencies); + auto du_inst_and_cmds = du_app_unit->create_flexible_du_unit(du_dependencies); srs_du::du& du_inst = *du_inst_and_cmds.unit; diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index 84fc744231..9b05753590 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -9,6 +9,7 @@ */ #include "gnb_appconfig_translators.h" +#include "apps/services/worker_manager_config.h" #include "apps/units/cu_cp/cu_cp_unit_config.h" #include "gnb_appconfig.h" #include "srsran/ran/subcarrier_spacing.h" @@ -44,3 +45,9 @@ srsran::sctp_network_connector_config srsran::generate_e2ap_nw_config(const gnb_ return out_cfg; } + +void srsran::fill_gnb_worker_manager_config(worker_manager_config& config, const gnb_appconfig& unit_cfg) +{ + config.nof_low_prio_threads = unit_cfg.expert_execution_cfg.threads.non_rt_threads.nof_non_rt_threads; + config.low_prio_sched_config = unit_cfg.expert_execution_cfg.affinities.low_priority_cpu_cfg; +} diff --git a/apps/gnb/gnb_appconfig_translators.h b/apps/gnb/gnb_appconfig_translators.h index 6831aa7fec..072fe33910 100644 --- a/apps/gnb/gnb_appconfig_translators.h +++ b/apps/gnb/gnb_appconfig_translators.h @@ -24,17 +24,18 @@ #include namespace srsran { -struct du_high_unit_cell_config; +struct gnb_appconfig; struct cu_cp_unit_amf_config; struct cu_cp_unit_config; struct cu_up_unit_config; struct du_high_unit_config; +struct du_high_unit_cell_config; struct du_low_unit_config; struct dynamic_du_unit_config; -struct gnb_appconfig; -struct rlc_am_appconfig; struct mac_lc_appconfig; +struct rlc_am_appconfig; +struct worker_manager_config; /// Converts and returns the subcarrier spacing. subcarrier_spacing generate_subcarrier_spacing(unsigned sc_spacing); @@ -42,4 +43,7 @@ subcarrier_spacing generate_subcarrier_spacing(unsigned sc_spacing); /// Converts and returns the given gnb application configuration to a E2AP Network Gateway configuration. srsran::sctp_network_connector_config generate_e2ap_nw_config(const gnb_appconfig& config, int ppid); +/// Fills the gNB worker manager parameters of the given worker manager configuration. +void fill_gnb_worker_manager_config(worker_manager_config& config, const gnb_appconfig& unit_cfg); + } // namespace srsran diff --git a/apps/services/worker_manager.cpp b/apps/services/worker_manager.cpp index 0b149af17f..1f072a5f61 100644 --- a/apps/services/worker_manager.cpp +++ b/apps/services/worker_manager.cpp @@ -17,94 +17,49 @@ using namespace srsran; static const uint32_t task_worker_queue_size = 2048; -static std::vector -build_affinity_manager_dependencies(const du_high_unit_cpu_affinities_cell_config& du_high_affinities, - const du_low_unit_cpu_affinities_cell_config& du_low_affinities, - const std::variant& ru_affinities) +worker_manager::worker_manager(const worker_manager_config& worker_cfg) : + low_prio_affinity_mng({worker_cfg.low_prio_sched_config}) { - std::vector out; - out.push_back(du_low_affinities.l1_ul_cpu_cfg); - out.push_back(du_low_affinities.l1_dl_cpu_cfg); - out.push_back(du_high_affinities.l2_cell_cpu_cfg); + // Check configuration. + { + unsigned ru_config_count = 0; + if (worker_cfg.ru_ofh_cfg) { + ++ru_config_count; + } + if (worker_cfg.ru_sdr_cfg) { + ++ru_config_count; + } + if (worker_cfg.ru_dummy_cfg) { + ++ru_config_count; + } - if (std::holds_alternative(ru_affinities)) { - out.push_back(std::get(ru_affinities).ru_cpu_cfg); + srsran_assert(ru_config_count <= 1, "Worker manager received configuration for more than one RU type"); } - else if (std::holds_alternative(ru_affinities)) { - out.push_back(std::get(ru_affinities).ru_cpu_cfg); - } else { - out.push_back(std::get(ru_affinities).ru_cpu_cfg); + if (worker_cfg.ru_ofh_cfg) { + ru_timing_mask = worker_cfg.ru_ofh_cfg.value().ru_timing_cpu; } - return out; -} - -worker_manager::worker_manager(const dynamic_du_unit_config& du_cfg, - const expert_execution_appconfig& expert_appcfg, - cu_cp_unit_pcap_config& cu_cp_pcap_cfg, - cu_up_unit_pcap_config& cu_up_pcap_cfg, - unsigned gtpu_queue_size) : - low_prio_affinity_mng({expert_appcfg.affinities.low_priority_cpu_cfg}) -{ - if (std::holds_alternative(du_cfg.ru_cfg)) { - ru_timing_mask = std::get(du_cfg.ru_cfg).config.expert_execution_cfg.ru_timing_cpu; + for (const auto& cell_affinities : worker_cfg.config_affinities) { + affinity_mng.emplace_back(cell_affinities); } - const unsigned nof_cells = du_cfg.du_high_cfg.config.expert_execution_cfg.cell_affinities.size(); - for (unsigned i = 0, e = nof_cells; i != e; ++i) { - std::variant - ru; - if (std::holds_alternative(du_cfg.ru_cfg)) { - ru = std::get(du_cfg.ru_cfg).expert_execution_cfg.cell_affinities[i]; - } else if (std::holds_alternative(du_cfg.ru_cfg)) { - ru = std::get(du_cfg.ru_cfg).config.expert_execution_cfg.cell_affinities[i]; - } else { - ru = std::get(du_cfg.ru_cfg).cell_affinities[i]; - } + create_low_prio_executors(worker_cfg); + associate_low_prio_executors(); - affinity_mng.emplace_back( - build_affinity_manager_dependencies(du_cfg.du_high_cfg.config.expert_execution_cfg.cell_affinities[i], - du_cfg.du_low_cfg.expert_execution_cfg.cell_affinities[i], - ru)); - } + create_du_executors(worker_cfg.du_hi_cfg, worker_cfg.du_low_cfg, worker_cfg.fapi_cfg); - if (std::holds_alternative(du_cfg.ru_cfg)) { - auto exec_cfg = std::get(du_cfg.ru_cfg).config.expert_execution_cfg; - for (auto& affinity_mask : exec_cfg.txrx_affinities) { - ru_txrx_affinity_masks.emplace_back(affinity_mask); - } - // If ru_txrx_cpus parameters are not specified, use the affinities of ru_cpus parameters of the cells. - if (ru_txrx_affinity_masks.empty()) { - for (unsigned i = 0, e = nof_cells; i != e; ++i) { - auto affinity_cfg = exec_cfg.cell_affinities[i].ru_cpu_cfg; - ru_txrx_affinity_masks.emplace_back(affinity_cfg.mask); - } - } + if (worker_cfg.ru_ofh_cfg) { + ru_txrx_affinity_masks = worker_cfg.ru_ofh_cfg.value().txrx_affinities; + create_ofh_executors(worker_cfg.ru_ofh_cfg.value()); } - - // Determine whether the gnb app is running in realtime or in simulated environment. - bool is_blocking_mode_active = false; - if (std::holds_alternative(du_cfg.ru_cfg)) { - const auto& sdr_cfg = std::get(du_cfg.ru_cfg); - is_blocking_mode_active = sdr_cfg.device_driver == "zmq"; + if (worker_cfg.ru_sdr_cfg) { + create_lower_phy_executors(worker_cfg.ru_sdr_cfg.value()); } - create_low_prio_executors(expert_appcfg, - cu_cp_pcap_cfg, - cu_up_pcap_cfg, - du_cfg.du_high_cfg.config.pcaps, - du_cfg.du_high_cfg.config.cells_cfg.size(), - gtpu_queue_size, - not is_blocking_mode_active); - associate_low_prio_executors(); - - create_du_executors(is_blocking_mode_active, nof_cells, du_cfg.du_low_cfg, du_cfg.fapi_cfg); - create_ru_executors(du_cfg.ru_cfg, du_cfg.du_high_cfg.config); + if (worker_cfg.ru_dummy_cfg) { + create_ru_dummy_executors(); + } } void worker_manager::stop() @@ -151,9 +106,7 @@ void worker_manager::create_prio_worker(const std::string& } void append_pcap_strands(std::vector& strand_list, - const cu_cp_unit_pcap_config& cu_cp_pcap_cfg, - const cu_up_unit_pcap_config& cu_up_pcap_cfg, - const du_high_unit_pcap_config& du_pcaps) + const worker_manager_config::pcap_config& config) { using namespace execution_config_helper; @@ -162,27 +115,26 @@ void append_pcap_strands(std::vector& strand_li // These layers have very low throughput, so no point in instantiating more than one strand. // This means that there is no parallelization in pcap writing across these layers. - if (cu_cp_pcap_cfg.f1ap.enabled or cu_cp_pcap_cfg.ngap.enabled or cu_cp_pcap_cfg.e1ap.enabled or - cu_up_pcap_cfg.e1ap.enabled or du_pcaps.f1ap.enabled or du_pcaps.e2ap.enabled) { + if (config.is_f1ap_enabled or config.is_ngap_enabled or config.is_e1ap_enabled or config.is_e2ap_enabled) { strand_list.emplace_back(base_strand_cfg); } - if (cu_up_pcap_cfg.n3.enabled) { + if (config.is_n3_enabled) { base_strand_cfg.queues[0].name = "n3_pcap_exec"; strand_list.emplace_back(base_strand_cfg); } - if (cu_up_pcap_cfg.f1u.enabled or du_pcaps.f1u.enabled) { + if (config.is_f1u_enabled) { base_strand_cfg.queues[0].name = "f1u_pcap_exec"; strand_list.emplace_back(base_strand_cfg); } - if (du_pcaps.mac.enabled) { + if (config.is_mac_enabled) { base_strand_cfg.queues[0].name = "mac_pcap_exec"; strand_list.emplace_back(base_strand_cfg); } - if (du_pcaps.rlc.enabled) { + if (config.is_rlc_enabled) { base_strand_cfg.queues[0].name = "rlc_pcap_exec"; strand_list.emplace_back(base_strand_cfg); } @@ -234,22 +186,21 @@ worker_manager::create_du_hi_slot_workers(unsigned nof_cells, bool rt_mode) return workers; } -void worker_manager::create_du_executors(bool is_blocking_mode_active, - unsigned nof_cells, - const du_low_unit_config& du_low, - const fapi_unit_config& fapi_cfg) +void worker_manager::create_du_executors(const worker_manager_config::du_high_config& du_hi, + std::optional du_low, + std::optional fapi_cfg) { using namespace execution_config_helper; const auto& exec_map = exec_mng.executors(); // FAPI message buffering executors. - fapi_exec.resize(nof_cells); - std::fill(fapi_exec.begin(), fapi_exec.end(), nullptr); - if (fapi_cfg.l2_nof_slots_ahead) { + if (fapi_cfg) { + fapi_exec.resize(fapi_cfg.value().nof_cells); + std::fill(fapi_exec.begin(), fapi_exec.end(), nullptr); // Create workers. - auto workers = create_fapi_workers(nof_cells); + auto workers = create_fapi_workers(fapi_cfg.value().nof_cells); - for (unsigned cell_id = 0; cell_id != nof_cells; ++cell_id) { + for (unsigned cell_id = 0; cell_id != fapi_cfg.value().nof_cells; ++cell_id) { const std::string exec_name = "fapi_exec#" + std::to_string(cell_id); workers[cell_id].executors.emplace_back(exec_name); // Create executor and associated workers. @@ -263,14 +214,14 @@ void worker_manager::create_du_executors(bool is_blocking_m } // Workers for handling cell slot indications of different cells. - auto slot_workers = create_du_hi_slot_workers(nof_cells, not is_blocking_mode_active); - for (unsigned cell_id = 0; cell_id != nof_cells; ++cell_id) { + auto slot_workers = create_du_hi_slot_workers(du_hi.nof_cells, du_hi.is_rt_mode_enabled); + for (unsigned cell_id = 0; cell_id != du_hi.nof_cells; ++cell_id) { const std::string cell_id_str = std::to_string(cell_id); slot_workers[cell_id].executors.push_back( - {"cell_exec#" + cell_id_str, task_priority::max - 1, {}, std::nullopt, is_blocking_mode_active}); + {"cell_exec#" + cell_id_str, task_priority::max - 1, {}, std::nullopt, !du_hi.is_rt_mode_enabled}); slot_workers[cell_id].executors.push_back( - {"slot_exec#" + cell_id_str, task_priority::max, {}, std::nullopt, is_blocking_mode_active}); + {"slot_exec#" + cell_id_str, task_priority::max, {}, std::nullopt, !du_hi.is_rt_mode_enabled}); if (not exec_mng.add_execution_context(create_execution_context(slot_workers[cell_id]))) { report_fatal_error("Failed to instantiate {} execution context", slot_workers[cell_id].name); @@ -278,8 +229,8 @@ void worker_manager::create_du_executors(bool is_blocking_m } // Instantiate DU-high executor mapper. - du_high_executors.resize(nof_cells); - for (unsigned i = 0; i != nof_cells; ++i) { + du_high_executors.resize(du_hi.nof_cells); + for (unsigned i = 0; i != du_hi.nof_cells; ++i) { auto& du_item = du_high_executors[i]; const std::string cell_id_str = std::to_string(i); @@ -298,45 +249,41 @@ void worker_manager::create_du_executors(bool is_blocking_m *exec_map.at("ctrl_exec")); } - const du_low_unit_expert_threads_config& upper_phy_threads_cfg = du_low.expert_execution_cfg.threads; - create_du_low_executors(is_blocking_mode_active, - upper_phy_threads_cfg.nof_ul_threads, - upper_phy_threads_cfg.nof_dl_threads, - upper_phy_threads_cfg.nof_pusch_decoder_threads, - nof_cells); + if (du_low) { + create_du_low_executors(du_low.value().is_blocking_mode_active, + du_low.value().nof_ul_threads, + du_low.value().nof_dl_threads, + du_low.value().nof_pusch_decoder_threads, + du_low.value().nof_cells); + } } -execution_config_helper::worker_pool -worker_manager::create_low_prio_workers(const expert_execution_appconfig& expert_appcfg) +execution_config_helper::worker_pool worker_manager::create_low_prio_workers(unsigned nof_low_prio_threads, + os_sched_affinity_bitmask low_prio_mask) { using namespace execution_config_helper; // Configure non-RT worker pool. worker_pool non_rt_pool{ "non_rt_pool", - expert_appcfg.threads.non_rt_threads.nof_non_rt_threads, + nof_low_prio_threads, {{concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, // two task priority levels. {concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}}, // Left empty, is filled later. {}, std::chrono::microseconds{100}, os_thread_realtime_priority::no_realtime(), - std::vector{expert_appcfg.affinities.low_priority_cpu_cfg.mask}}; + std::vector{low_prio_mask}}; return non_rt_pool; } -void worker_manager::create_low_prio_executors(const expert_execution_appconfig& expert_appcfg, - const cu_cp_unit_pcap_config& cu_cp_pcaps, - const cu_up_unit_pcap_config& cu_up_pcaps, - const du_high_unit_pcap_config& du_pcaps, - unsigned nof_cells, - unsigned gtpu_queue_size, - bool rt_mode) +void worker_manager::create_low_prio_executors(const worker_manager_config& worker_cfg) { using namespace execution_config_helper; // TODO: split executor creation and association to workers - worker_pool non_rt_pool = create_low_prio_workers(expert_appcfg); + worker_pool non_rt_pool = + create_low_prio_workers(worker_cfg.nof_low_prio_threads, worker_cfg.low_prio_sched_config.mask); // Associate executors to the worker pool. // Used for PCAP writing. @@ -354,39 +301,42 @@ void worker_manager::create_low_prio_executors(const expert_execution_appconfig& std::vector& cu_up_strands = non_rt_pool.executors[2].strands; // Configuration of strands for PCAP writing. These strands will use the low priority executor. - append_pcap_strands(low_prio_strands, cu_cp_pcaps, cu_up_pcaps, du_pcaps); + append_pcap_strands(low_prio_strands, worker_cfg.pcap_cfg); // Configuration of strand for the control plane handling (CU-CP and DU-high control plane). // This strand will support two priority levels, the highest being for timer management. // Note: In case of non-RT operation, we make the timer_exec synchronous. This will have the effect of stopping // the lower layers from running faster than this strand. - strand cp_strand{{{"timer_exec", concurrent_queue_policy::lockfree_spsc, task_worker_queue_size, not rt_mode}, + strand cp_strand{{{"timer_exec", + concurrent_queue_policy::lockfree_spsc, + task_worker_queue_size, + not worker_cfg.du_hi_cfg.is_rt_mode_enabled}, {"ctrl_exec", concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}}}; high_prio_strands.push_back(cp_strand); // Setup strands for the data plane of all the instantiated DUs. // One strand per DU, each with multiple priority levels. - for (unsigned i = 0; i != nof_cells; ++i) { - low_prio_strands.push_back( - strand{{{fmt::format("du_rb_prio_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, - {fmt::format("du_rb_ul_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, gtpu_queue_size}, - {fmt::format("du_rb_dl_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, gtpu_queue_size}}}); + for (unsigned i = 0; i != worker_cfg.du_hi_cfg.nof_cells; ++i) { + low_prio_strands.push_back(strand{ + {{fmt::format("du_rb_prio_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, + {fmt::format("du_rb_ul_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, worker_cfg.gtpu_queue_size}, + {fmt::format("du_rb_dl_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, worker_cfg.gtpu_queue_size}}}); } // Configuration of strands for user plane handling (CU-UP and DU-low user plane). Given that the CU-UP doesn't - // currently support multithreading, these strands will point to a strand that interfaces with the non-RT thread pool. - // Each UE strand will have three queues, one for timer management and configuration, one for DL data plane and one - // for UL data plane. + // currently support multithreading, these strands will point to a strand that interfaces with the non-RT thread + // pool. Each UE strand will have three queues, one for timer management and configuration, one for DL data plane + // and one for UL data plane. cu_up_strands.push_back( strand{{{"cu_up_ctrl_exec", concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, {"cu_up_io_ul_exec", concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}}}); for (unsigned i = 0; i != nof_cu_up_ue_strands; ++i) { - cu_up_strands.push_back( - strand{{{fmt::format("ue_up_ctrl_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, - {fmt::format("ue_up_ul_exec#{}", i), - concurrent_queue_policy::lockfree_mpmc, - gtpu_queue_size}, // TODO: Consider separate param for size of UL queue if needed. - {fmt::format("ue_up_dl_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, gtpu_queue_size}}}); + cu_up_strands.push_back(strand{ + {{fmt::format("ue_up_ctrl_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, + {fmt::format("ue_up_ul_exec#{}", i), + concurrent_queue_policy::lockfree_mpmc, + worker_cfg.gtpu_queue_size}, // TODO: Consider separate param for size of UL queue if needed. + {fmt::format("ue_up_dl_exec#{}", i), concurrent_queue_policy::lockfree_mpmc, worker_cfg.gtpu_queue_size}}}); } // Create non-RT worker pool. @@ -529,15 +479,14 @@ void worker_manager::create_du_low_executors(bool is_blocking_mode_active, } } -void worker_manager::create_ofh_executors(const ru_ofh_unit_expert_execution_config& ru_cfg, - span cell_dl_antennas) +void worker_manager::create_ofh_executors(const worker_manager_config::ru_ofh_config& config) { using namespace execution_config_helper; // Maximum number of threads per cell. Implementation defined. The 3 threads are: transmission, reception and // codification. static constexpr unsigned MAX_NUM_THREADS_PER_CELL = 3U; - const unsigned nof_cells = ru_cfg.cell_affinities.size(); + const unsigned nof_cells = config.nof_downlink_antennas.size(); unsigned nof_host_threads = std::max(4U, std::max(std::thread::hardware_concurrency(), 4U) - 3U); @@ -575,7 +524,7 @@ void worker_manager::create_ofh_executors(const ru_ofh_unit_expert_execution_con { ru_dl_exec.emplace_back(); unsigned nof_ofh_dl_workers = - (ru_cfg.threads.is_downlink_parallelized) ? std::max(cell_dl_antennas[i] / 2U, 1U) : 1U; + (config.is_downlink_parallelized) ? std::max(config.nof_downlink_antennas[i] / 2U, 1U) : 1U; const std::string name = "ru_dl_#" + std::to_string(i); const std::string exec_name = "ru_dl_exec_#" + std::to_string(i); @@ -627,7 +576,7 @@ void worker_manager::create_ofh_executors(const ru_ofh_unit_expert_execution_con } } -void worker_manager::create_lower_phy_executors(lower_phy_thread_profile lower_phy_profile, unsigned nof_cells) +void worker_manager::create_lower_phy_executors(const worker_manager_config::ru_sdr_config& config) { using namespace execution_config_helper; @@ -645,9 +594,9 @@ void worker_manager::create_lower_phy_executors(lower_phy_thread_profile lower_p low_prio_affinity_mng.calcute_affinity_mask(sched_affinity_mask_types::low_priority)); ru_printer_exec = exec_mng.executors().at("ru_printer_exec"); - for (unsigned cell_id = 0; cell_id != nof_cells; ++cell_id) { - switch (lower_phy_profile) { - case lower_phy_thread_profile::blocking: { + for (unsigned cell_id = 0; cell_id != config.nof_cells; ++cell_id) { + switch (config.profile) { + case worker_manager_config::ru_sdr_config::lower_phy_thread_profile::blocking: { fmt::print("Lower PHY in executor blocking mode.\n"); std::string name = "phy_worker"; std::string exec_name = "phy_exec"; @@ -660,7 +609,7 @@ void worker_manager::create_lower_phy_executors(lower_phy_thread_profile lower_p lower_phy_ul_exec.push_back(phy_exec); break; } - case lower_phy_thread_profile::single: { + case worker_manager_config::ru_sdr_config::lower_phy_thread_profile::single: { fmt::print("Lower PHY in single executor mode.\n"); const std::string name = "lower_phy#" + std::to_string(cell_id); const std::string exec_name = "lower_phy_exec#" + std::to_string(cell_id); @@ -680,7 +629,7 @@ void worker_manager::create_lower_phy_executors(lower_phy_thread_profile lower_p lower_prach_exec.push_back(exec_mng.executors().at("prach_exec#" + std::to_string(cell_id))); break; } - case lower_phy_thread_profile::dual: { + case worker_manager_config::ru_sdr_config::lower_phy_thread_profile::dual: { fmt::print("Lower PHY in dual executor mode.\n"); const std::string name_dl = "lower_phy_dl#" + std::to_string(cell_id); const std::string exec_dl = "lower_phy_dl_exec#" + std::to_string(cell_id); @@ -706,7 +655,7 @@ void worker_manager::create_lower_phy_executors(lower_phy_thread_profile lower_p lower_prach_exec.push_back(exec_mng.executors().at("prach_exec#" + std::to_string(cell_id))); break; } - case lower_phy_thread_profile::quad: { + case worker_manager_config::ru_sdr_config::lower_phy_thread_profile::quad: { fmt::print("Lower PHY in quad executor mode.\n"); const std::string name_dl = "lower_phy_dl#" + std::to_string(cell_id); const std::string exec_dl = "lower_phy_dl_exec#" + std::to_string(cell_id); @@ -750,31 +699,8 @@ void worker_manager::create_lower_phy_executors(lower_phy_thread_profile lower_p } } -void worker_manager::create_ru_executors( - const std::variant& ru_cfg, - const du_high_unit_config& du_high) +void worker_manager::create_ru_dummy_executors() { - if (std::holds_alternative(ru_cfg)) { - std::vector cell_antennas_dl; - for (const auto& cell : du_high.cells_cfg) { - cell_antennas_dl.push_back(cell.cell.nof_antennas_dl); - } - - create_ofh_executors(std::get(ru_cfg).config.expert_execution_cfg, cell_antennas_dl); - - return; - } - - if (std::holds_alternative(ru_cfg)) { - const ru_sdr_unit_config& sdr_cfg = std::get(ru_cfg); - std::string driver = sdr_cfg.device_driver; - - create_lower_phy_executors((driver != "zmq") ? sdr_cfg.expert_execution_cfg.threads.execution_profile - : lower_phy_thread_profile::blocking, - sdr_cfg.expert_execution_cfg.cell_affinities.size()); - return; - } - // Use the first cell of the affinity manager for the dummy RU. create_prio_worker("ru_dummy", task_worker_queue_size, diff --git a/apps/services/worker_manager.h b/apps/services/worker_manager.h index e6b9d88ef0..7d8c475651 100644 --- a/apps/services/worker_manager.h +++ b/apps/services/worker_manager.h @@ -10,12 +10,8 @@ #pragma once -#include "../gnb/gnb_appconfig.h" -#include "../units/flexible_du/split_dynamic/dynamic_du_unit_config.h" +#include "apps/services/worker_manager_config.h" #include "apps/services/worker_manager_worker_getter.h" -#include "apps/units/cu_cp/cu_cp_unit_pcap_config.h" -#include "apps/units/cu_up/cu_up_unit_pcap_config.h" -#include "os_sched_affinity_manager.h" #include "srsran/cu_up/cu_up_executor_pool.h" #include "srsran/du/du_high/du_high_executor_mapper.h" #include "srsran/support/executors/task_execution_manager.h" @@ -25,11 +21,7 @@ namespace srsran { /// Manages the workers of the app. struct worker_manager : public worker_manager_executor_getter { - worker_manager(const dynamic_du_unit_config& du_cfg, - const expert_execution_appconfig& expert_appcfg, - cu_cp_unit_pcap_config& cu_cp_pcap_cfg, - cu_up_unit_pcap_config& cu_up_pcap_cfg, - unsigned gtpu_queue_size); + worker_manager(const worker_manager_config& config); void stop(); @@ -122,14 +114,9 @@ struct worker_manager : public worker_manager_executor_getter { os_thread_realtime_priority prio = os_thread_realtime_priority::no_realtime(), span cpu_masks = {}); - execution_config_helper::worker_pool create_low_prio_workers(const expert_execution_appconfig& expert_appcfg); - void create_low_prio_executors(const expert_execution_appconfig& expert_appcfg, - const cu_cp_unit_pcap_config& cu_cp_pcaps, - const cu_up_unit_pcap_config& cu_up_pcaps, - const du_high_unit_pcap_config& du_pcaps, - unsigned nof_cells, - unsigned gtpu_queue_size, - bool rt_mode); + execution_config_helper::worker_pool create_low_prio_workers(unsigned nof_low_prio_threads, + os_sched_affinity_bitmask low_prio_mask); + void create_low_prio_executors(const worker_manager_config& config); void associate_low_prio_executors(); std::vector create_fapi_workers(unsigned nof_cells); @@ -138,10 +125,9 @@ struct worker_manager : public worker_manager_executor_getter { bool rt_mode); /// Helper method that creates the Distributed Unit executors. - void create_du_executors(bool is_blocking_mode_active, - unsigned nof_cells, - const du_low_unit_config& du_low, - const fapi_unit_config& fapi_cfg); + void create_du_executors(const worker_manager_config::du_high_config& du_hi, + std::optional du_low, + std::optional fapi_cfg); /// Helper method that creates the low Distributed Unit executors. void create_du_low_executors(bool is_blocking_mode_active, @@ -150,16 +136,14 @@ struct worker_manager : public worker_manager_executor_getter { unsigned nof_pusch_decoder_workers, unsigned nof_cells); - /// Helper method that creates the Radio Unit executors. - void - create_ru_executors(const std::variant& ru_cfg, - const du_high_unit_config& du_high); + /// Helper method that creates the Radio Unit dummy executors. + void create_ru_dummy_executors(); /// Helper method that creates the lower PHY executors. - void create_lower_phy_executors(lower_phy_thread_profile lower_phy_profile, unsigned nof_cells); + void create_lower_phy_executors(const worker_manager_config::ru_sdr_config& config); /// Helper method that creates the Open Fronthaul executors. - void create_ofh_executors(const ru_ofh_unit_expert_execution_config& ru_cfg, span cell_dl_antennas); + void create_ofh_executors(const worker_manager_config::ru_ofh_config& config); }; } // namespace srsran diff --git a/apps/services/worker_manager_config.h b/apps/services/worker_manager_config.h new file mode 100644 index 0000000000..5962eea8f2 --- /dev/null +++ b/apps/services/worker_manager_config.h @@ -0,0 +1,108 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "os_sched_affinity_manager.h" + +namespace srsran { + +/// Worker manager configuration. +struct worker_manager_config { + /// RU OFH worker configuration. + struct ru_ofh_config { + bool is_downlink_parallelized; + /// Number of downlink antennas indexed by cell. + std::vector nof_downlink_antennas; + /// RU timing CPU affinity mask. + os_sched_affinity_bitmask ru_timing_cpu; + /// Vector of affinities for the txrx workers. + std::vector txrx_affinities; + }; + + /// RU SDR worker configuration. + struct ru_sdr_config { + /// Lower physical layer thread profiles. + enum class lower_phy_thread_profile { + /// Same task worker as the rest of the PHY (ZMQ only). + blocking = 0, + /// Single task worker for all the lower physical layer task executors. + single, + /// Two task workers - one for the downlink and one for the uplink. + dual, + /// Dedicated task workers for each of the subtasks (downlink processing, uplink processing, reception and + /// transmission). + quad + }; + + lower_phy_thread_profile profile; + unsigned nof_cells; + }; + + /// RU dummy worker configuration. + struct ru_dummy_config {}; + + /// FAPI worker configuration. + struct fapi_config { + unsigned nof_cells; + }; + + /// DU low worker configuration. + struct du_low_config { + bool is_blocking_mode_active; + unsigned nof_ul_threads; + unsigned nof_dl_threads; + unsigned nof_pusch_decoder_threads; + unsigned nof_cells; + }; + + /// DU high worker configuration. + struct du_high_config { + unsigned nof_cells; + bool is_rt_mode_enabled = true; + }; + + /// PCAP worker configuration. + struct pcap_config { + bool is_f1ap_enabled = false; + bool is_ngap_enabled = false; + bool is_e1ap_enabled = false; + bool is_e2ap_enabled = false; + bool is_n3_enabled = false; + bool is_f1u_enabled = false; + bool is_mac_enabled = false; + bool is_rlc_enabled = false; + }; + + /// Number of low priority threads. + unsigned nof_low_prio_threads; + /// Low priority CPU bitmasks. + os_sched_affinity_config low_prio_sched_config; + /// DU high configuration. + du_high_config du_hi_cfg; + /// PCAP configuration. + pcap_config pcap_cfg; + /// GTPU queue size. + unsigned gtpu_queue_size; + /// Vector of affinities mask indexed by cell. + std::vector> config_affinities; + /// FAPI configuration. + std::optional fapi_cfg; + /// DU low configuration + std::optional du_low_cfg; + /// RU SDR configuration. + std::optional ru_sdr_cfg; + /// RU OFH configuration. + std::optional ru_ofh_cfg; + /// RU dummy configuration. + std::optional ru_dummy_cfg; +}; + +} // namespace srsran diff --git a/apps/units/application_unit.h b/apps/units/application_unit.h index a923105df6..22f0bb4335 100644 --- a/apps/units/application_unit.h +++ b/apps/units/application_unit.h @@ -15,6 +15,7 @@ class App; } // namespace CLI namespace srsran { +struct os_sched_affinity_bitmask; /// \brief Application unit interface. /// @@ -29,8 +30,11 @@ class application_unit /// Registers the parsing configuration properties that will be used by this application unit. virtual void on_parsing_configuration_registration(CLI::App& app) = 0; + /// Auto derive configuration parameters. + virtual void on_configuration_parameters_autoderivation(CLI::App& app) = 0; + /// Validates the configuration of this application unit. Returns true on success, otherwise false. - virtual bool on_configuration_validation() const = 0; + virtual bool on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const = 0; /// Registers the loggers of this application unit. virtual void on_loggers_registration() = 0; diff --git a/apps/units/cu_cp/cu_cp_application_unit_impl.cpp b/apps/units/cu_cp/cu_cp_application_unit_impl.cpp index 4ad8cf0bec..d8176ac142 100644 --- a/apps/units/cu_cp/cu_cp_application_unit_impl.cpp +++ b/apps/units/cu_cp/cu_cp_application_unit_impl.cpp @@ -20,7 +20,7 @@ void cu_cp_application_unit_impl::on_parsing_configuration_registration(CLI::App configure_cli11_with_cu_cp_unit_config_schema(app, unit_cfg); } -bool cu_cp_application_unit_impl::on_configuration_validation() const +bool cu_cp_application_unit_impl::on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const { return validate_cu_cp_unit_config(unit_cfg); } diff --git a/apps/units/cu_cp/cu_cp_application_unit_impl.h b/apps/units/cu_cp/cu_cp_application_unit_impl.h index 2e41c0d2e8..876a9b9351 100644 --- a/apps/units/cu_cp/cu_cp_application_unit_impl.h +++ b/apps/units/cu_cp/cu_cp_application_unit_impl.h @@ -23,7 +23,7 @@ class cu_cp_application_unit_impl : public application_unit void on_parsing_configuration_registration(CLI::App& app) override; // See interface for documentation. - bool on_configuration_validation() const override; + bool on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const override; // See interface for documentation. void on_loggers_registration() override; diff --git a/apps/units/cu_cp/cu_cp_config_translators.cpp b/apps/units/cu_cp/cu_cp_config_translators.cpp index cb2e651202..0d830a5376 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.cpp +++ b/apps/units/cu_cp/cu_cp_config_translators.cpp @@ -9,6 +9,7 @@ */ #include "cu_cp_config_translators.h" +#include "apps/services/worker_manager_config.h" #include "cu_cp_unit_config.h" #include "srsran/cu_cp/cu_cp_configuration_helpers.h" #include "srsran/ran/plmn_identity.h" @@ -488,3 +489,17 @@ srs_cu_cp::n2_connection_client_config srsran::generate_n2_client_config(bool return srs_cu_cp::n2_connection_client_config{pcap_writer, mode}; } + +void srsran::fill_cu_cp_worker_manager_config(worker_manager_config& config, const cu_cp_unit_config& unit_cfg) +{ + auto& pcap_cfg = config.pcap_cfg; + if (unit_cfg.pcap_cfg.e1ap.enabled) { + pcap_cfg.is_e1ap_enabled = true; + } + if (unit_cfg.pcap_cfg.f1ap.enabled) { + pcap_cfg.is_f1ap_enabled = true; + } + if (unit_cfg.pcap_cfg.ngap.enabled) { + pcap_cfg.is_ngap_enabled = true; + } +} diff --git a/apps/units/cu_cp/cu_cp_config_translators.h b/apps/units/cu_cp/cu_cp_config_translators.h index 4fa97739e0..15fa3e671d 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.h +++ b/apps/units/cu_cp/cu_cp_config_translators.h @@ -17,6 +17,7 @@ namespace srsran { struct cu_cp_unit_config; struct cu_cp_unit_amf_config_item; +struct worker_manager_config; /// Converts and returns the given gnb application configuration to a CU-CP configuration. srs_cu_cp::cu_cp_configuration generate_cu_cp_config(const cu_cp_unit_config& cu_cfg); @@ -27,4 +28,7 @@ srs_cu_cp::n2_connection_client_config generate_n2_client_config(bool dlt_pcap& pcap_writer, io_broker& broker); +/// Fills the CU-CP worker manager parameters of the given worker manager configuration. +void fill_cu_cp_worker_manager_config(worker_manager_config& config, const cu_cp_unit_config& unit_cfg); + } // namespace srsran diff --git a/apps/units/cu_up/cu_up_application_unit_impl.cpp b/apps/units/cu_up/cu_up_application_unit_impl.cpp index 04261c064f..aa6a0990f5 100644 --- a/apps/units/cu_up/cu_up_application_unit_impl.cpp +++ b/apps/units/cu_up/cu_up_application_unit_impl.cpp @@ -20,7 +20,7 @@ void cu_up_application_unit_impl::on_parsing_configuration_registration(CLI::App configure_cli11_with_cu_up_unit_config_schema(app, unit_cfg); } -bool cu_up_application_unit_impl::on_configuration_validation() const +bool cu_up_application_unit_impl::on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const { return validate_cu_up_unit_config(unit_cfg); } diff --git a/apps/units/cu_up/cu_up_application_unit_impl.h b/apps/units/cu_up/cu_up_application_unit_impl.h index 657e48c296..4b9457c944 100644 --- a/apps/units/cu_up/cu_up_application_unit_impl.h +++ b/apps/units/cu_up/cu_up_application_unit_impl.h @@ -23,7 +23,7 @@ class cu_up_application_unit_impl : public application_unit void on_parsing_configuration_registration(CLI::App& app) override; // See interface for documentation. - bool on_configuration_validation() const override; + bool on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const override; // See interface for documentation. void on_loggers_registration() override; diff --git a/apps/units/cu_up/cu_up_unit_config_translators.cpp b/apps/units/cu_up/cu_up_unit_config_translators.cpp index 9f94399b56..4f54c2d4bf 100644 --- a/apps/units/cu_up/cu_up_unit_config_translators.cpp +++ b/apps/units/cu_up/cu_up_unit_config_translators.cpp @@ -9,6 +9,7 @@ */ #include "cu_up_unit_config_translators.h" +#include "apps/services/worker_manager_config.h" #include "cu_up_unit_config.h" #include "srsran/cu_up/cu_up_configuration_helpers.h" #include "srsran/rlc/rlc_config.h" @@ -63,3 +64,19 @@ srsran::generate_cu_up_qos_config(const cu_up_unit_config& cu_up_config) } return out_cfg; } + +void srsran::fill_cu_up_worker_manager_config(worker_manager_config& config, const cu_up_unit_config& unit_cfg) +{ + config.gtpu_queue_size = unit_cfg.gtpu_queue_size; + + auto& pcap_cfg = config.pcap_cfg; + if (unit_cfg.pcap_cfg.e1ap.enabled) { + pcap_cfg.is_e1ap_enabled = true; + } + if (unit_cfg.pcap_cfg.n3.enabled) { + pcap_cfg.is_n3_enabled = true; + } + if (unit_cfg.pcap_cfg.f1u.enabled) { + pcap_cfg.is_f1u_enabled = true; + } +} diff --git a/apps/units/cu_up/cu_up_unit_config_translators.h b/apps/units/cu_up/cu_up_unit_config_translators.h index 9ad7c1e77c..18a2376305 100644 --- a/apps/units/cu_up/cu_up_unit_config_translators.h +++ b/apps/units/cu_up/cu_up_unit_config_translators.h @@ -15,6 +15,7 @@ namespace srsran { struct cu_up_unit_config; +struct worker_manager_config; /// Converts and returns the given gnb application configuration to a CU-UP configuration. srs_cu_up::cu_up_configuration generate_cu_up_config(const cu_up_unit_config& config); @@ -22,4 +23,7 @@ srs_cu_up::cu_up_configuration generate_cu_up_config(const cu_up_unit_config& co /// Converts and returns the given gnb application QoS configuration to a CU-UP configuration. std::map generate_cu_up_qos_config(const cu_up_unit_config& cu_up_config); +/// Fills the CU-UP worker manager parameters of the given worker manager configuration. +void fill_cu_up_worker_manager_config(worker_manager_config& config, const cu_up_unit_config& unit_cfg); + } // namespace srsran diff --git a/apps/units/flexible_du/du_high/du_high_config.h b/apps/units/flexible_du/du_high/du_high_config.h index 805b06f87a..62653d0a12 100644 --- a/apps/units/flexible_du/du_high/du_high_config.h +++ b/apps/units/flexible_du/du_high/du_high_config.h @@ -851,6 +851,9 @@ struct du_high_unit_config { std::map srb_cfg; /// E2 configuration. du_high_unit_e2_config e2_cfg; + + /// Returns true if testmode is enabled, false otherwise. + bool is_testmode_enabled() const { return test_mode_cfg.test_ue.rnti != rnti_t::INVALID_RNTI; } }; /// DU high configuration. diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index b3653875c7..e5ff9de10d 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -9,6 +9,7 @@ */ #include "du_high_config_translators.h" +#include "apps/services/worker_manager_config.h" #include "du_high_config.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/du/du_cell_config_validation.h" @@ -935,3 +936,35 @@ void srsran::ntn_augment_rlc_parameters(const ntn_config& ntn_cfg, std::map generate_du_cell_config(const du_high_unit_config& config); @@ -52,4 +53,9 @@ generate_du_slicing_rrm_policy_config(span span slice_cfg, unsigned nof_cell_crbs); +/// Fills the DU high worker manager parameters of the given worker manager configuration. +void fill_du_high_worker_manager_config(worker_manager_config& config, + const du_high_unit_config& unit_cfg, + bool is_blocking_mode_enabled = false); + } // namespace srsran diff --git a/apps/units/flexible_du/du_low/du_low_config_cli11_schema.cpp b/apps/units/flexible_du/du_low/du_low_config_cli11_schema.cpp index 391f1a75d1..594e83d800 100644 --- a/apps/units/flexible_du/du_low/du_low_config_cli11_schema.cpp +++ b/apps/units/flexible_du/du_low/du_low_config_cli11_schema.cpp @@ -312,7 +312,7 @@ void srsran::configure_cli11_with_du_low_config_schema(CLI::App& app, du_low_uni void srsran::autoderive_du_low_parameters_after_parsing(CLI::App& app, du_low_unit_config& parsed_cfg, duplex_mode mode, - bool is_zmq_rf_driver, + bool is_blocking_mode_enabled, unsigned nof_cells) { // If max proc delay property is not present in the config, configure the default value. @@ -336,7 +336,7 @@ void srsran::autoderive_du_low_parameters_after_parsing(CLI::App& app, } // Ignore the default settings based in the number of CPU cores for ZMQ. - if (is_zmq_rf_driver) { + if (is_blocking_mode_enabled) { du_low_unit_expert_threads_config& upper = parsed_cfg.expert_execution_cfg.threads; upper.nof_pusch_decoder_threads = 0; upper.nof_ul_threads = 1; diff --git a/apps/units/flexible_du/du_low/du_low_config_cli11_schema.h b/apps/units/flexible_du/du_low/du_low_config_cli11_schema.h index 65dd1394c7..e7b197e7fc 100644 --- a/apps/units/flexible_du/du_low/du_low_config_cli11_schema.h +++ b/apps/units/flexible_du/du_low/du_low_config_cli11_schema.h @@ -24,7 +24,7 @@ void configure_cli11_with_du_low_config_schema(CLI::App& app, du_low_unit_config void autoderive_du_low_parameters_after_parsing(CLI::App& app, du_low_unit_config& parsed_cfg, duplex_mode mode, - bool is_zmq_rf_driver, + bool is_blocking_mode_enabled, unsigned nof_cells); } // namespace srsran diff --git a/apps/units/flexible_du/du_low/du_low_config_translator.cpp b/apps/units/flexible_du/du_low/du_low_config_translator.cpp index 84e4252175..5c0cad3527 100644 --- a/apps/units/flexible_du/du_low/du_low_config_translator.cpp +++ b/apps/units/flexible_du/du_low/du_low_config_translator.cpp @@ -9,6 +9,7 @@ */ #include "du_low_config_translator.h" +#include "apps/services/worker_manager_config.h" #include "du_low_config.h" #include "srsran/du/du_cell_config.h" #include "srsran/phy/upper/upper_phy_factories.h" @@ -170,3 +171,26 @@ void srsran::generate_du_low_wrapper_config(srs_du::du_low_wrapper_config& generate_du_low_config(out_config.du_low_cfg, du_low_unit_cfg, hal_config, du_cells, max_puschs_per_slot, du_id); out_config.prach_ports = std::move(prach_ports); } + +void srsran::fill_du_low_worker_manager_config(worker_manager_config& config, + const du_low_unit_config& unit_cfg, + unsigned is_blocking_mode_active, + unsigned nof_cells) +{ + auto& du_low_cfg = config.du_low_cfg.emplace(); + + du_low_cfg.is_blocking_mode_active = is_blocking_mode_active; + du_low_cfg.nof_cells = nof_cells; + + du_low_cfg.nof_dl_threads = unit_cfg.expert_execution_cfg.threads.nof_dl_threads; + du_low_cfg.nof_ul_threads = unit_cfg.expert_execution_cfg.threads.nof_ul_threads; + du_low_cfg.nof_pusch_decoder_threads = unit_cfg.expert_execution_cfg.threads.nof_pusch_decoder_threads; + + srsran_assert(config.config_affinities.size() == unit_cfg.expert_execution_cfg.cell_affinities.size(), + "Invalid number of cell affinities"); + + for (unsigned i = 0, e = nof_cells; i != e; ++i) { + config.config_affinities[i].push_back(unit_cfg.expert_execution_cfg.cell_affinities[i].l1_dl_cpu_cfg); + config.config_affinities[i].push_back(unit_cfg.expert_execution_cfg.cell_affinities[i].l1_ul_cpu_cfg); + } +} diff --git a/apps/units/flexible_du/du_low/du_low_config_translator.h b/apps/units/flexible_du/du_low/du_low_config_translator.h index a123b0ed2b..c00fb84e15 100644 --- a/apps/units/flexible_du/du_low/du_low_config_translator.h +++ b/apps/units/flexible_du/du_low/du_low_config_translator.h @@ -21,6 +21,7 @@ struct du_low_config; } // namespace srs_du struct du_low_unit_config; +struct worker_manager_config; void generate_du_low_wrapper_config(srs_du::du_low_wrapper_config& out_config, const du_low_unit_config& du_low_unit_cfg, @@ -30,4 +31,10 @@ void generate_du_low_wrapper_config(srs_du::du_low_wrapper_config& span max_puschs_per_slot, unsigned du_id); +/// Fills the DU low worker manager parameters of the given worker manager configuration. +void fill_du_low_worker_manager_config(worker_manager_config& config, + const du_low_unit_config& unit_cfg, + unsigned is_blocking_mode_active, + unsigned nof_cells); + } // namespace srsran diff --git a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp index da9221655c..e751a1af59 100644 --- a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp +++ b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp @@ -10,8 +10,10 @@ #include "du_low_wrapper_config_helper.h" #include "apps/services/worker_manager.h" +#include "du_low_config.h" #include "du_low_config_translator.h" #include "srsran/du/du_low/du_low_wrapper_factory.h" +#include "srsran/ran/slot_pdu_capacity_constants.h" using namespace srsran; diff --git a/apps/units/flexible_du/fapi/CMakeLists.txt b/apps/units/flexible_du/fapi/CMakeLists.txt index 246cd56db6..723b3b92ac 100644 --- a/apps/units/flexible_du/fapi/CMakeLists.txt +++ b/apps/units/flexible_du/fapi/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES fapi_config_cli11_schema.cpp + fapi_config_translator.cpp fapi_config_yaml_writer.cpp) add_library(srsran_fapi_app_unit STATIC ${SOURCES}) diff --git a/apps/units/flexible_du/fapi/fapi_config_translator.cpp b/apps/units/flexible_du/fapi/fapi_config_translator.cpp new file mode 100644 index 0000000000..5b2a77ec31 --- /dev/null +++ b/apps/units/flexible_du/fapi/fapi_config_translator.cpp @@ -0,0 +1,28 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "fapi_config_translator.h" +#include "apps/services/worker_manager_config.h" +#include "fapi_config.h" + +using namespace srsran; + +void srsran::fill_fapi_worker_manager_config(worker_manager_config& config, + const fapi_unit_config& unit_cfg, + unsigned nof_cells) +{ + // No configuration for FAPI if there is no buffered module. + if (unit_cfg.l2_nof_slots_ahead == 0) { + return; + } + + auto& fapi_cfg = config.fapi_cfg.emplace(); + fapi_cfg.nof_cells = nof_cells; +} \ No newline at end of file diff --git a/apps/units/flexible_du/fapi/fapi_config_translator.h b/apps/units/flexible_du/fapi/fapi_config_translator.h new file mode 100644 index 0000000000..23554f9a01 --- /dev/null +++ b/apps/units/flexible_du/fapi/fapi_config_translator.h @@ -0,0 +1,23 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +namespace srsran { + +struct fapi_unit_config; +struct worker_manager_config; + +/// Fills the FAPI worker manager parameters of the given worker manager configuration. +void fill_fapi_worker_manager_config(worker_manager_config& config, + const fapi_unit_config& unit_cfg, + unsigned nof_cells); + +} // namespace srsran diff --git a/apps/units/flexible_du/flexible_du_application_unit.h b/apps/units/flexible_du/flexible_du_application_unit.h new file mode 100644 index 0000000000..fb3d35ff74 --- /dev/null +++ b/apps/units/flexible_du/flexible_du_application_unit.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/application_unit.h" +#include "apps/units/flexible_du/du_unit.h" +#include + +namespace srsran { +struct worker_manager_config; +struct du_high_unit_config; + +/// Flexible DU application unit interface. +class flexible_du_application_unit : public application_unit +{ +public: + virtual ~flexible_du_application_unit() = default; + + /// Creates a flexible DU using the given dependencies. + virtual du_unit create_flexible_du_unit(const du_unit_dependencies& dependencies) = 0; + + /// Returns the DU high unit configuration of this flexible DU. + virtual du_high_unit_config& get_du_high_unit_config() = 0; + virtual const du_high_unit_config& get_du_high_unit_config() const = 0; + + /// Dumps the flexible DU configuration into the given YAML node. + virtual void dump_config(YAML::Node& node) const = 0; + + /// Fills the given worker manager configuration with the flexible parameters. + virtual void fill_worker_manager_config(worker_manager_config& config) = 0; +}; + +/// \brief Creates a flexible DU application unit. +/// +/// Different splits must provide an implementation of this free function so the applications can instantiate a flexible +/// DU application unit. Only one of these implementations should be compiled, based on the DU_SPLIT_TYPE cmake +/// definition. +std::unique_ptr create_flexible_du_application_unit(); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp index 3e5cd26357..ca89cfb5a7 100644 --- a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp +++ b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp @@ -9,8 +9,13 @@ */ #include "split6_du_application_unit_impl.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/du_high/du_high_config_yaml_writer.h" +#include "apps/units/flexible_du/fapi/fapi_config_translator.h" +#include "apps/units/flexible_du/fapi/fapi_config_yaml_writer.h" #include "split6_du_factory.h" #include "split6_du_unit_cli11_schema.h" +#include "split6_du_unit_config_validator.h" #include "split6_du_unit_logger_registrator.h" using namespace srsran; @@ -21,13 +26,18 @@ void split6_du_application_unit_impl::on_loggers_registration() plugin->on_loggers_registration(); } -bool split6_du_application_unit_impl::on_configuration_validation() const +void split6_du_application_unit_impl::on_configuration_parameters_autoderivation(CLI::App& app) +{ + autoderive_split6_du_parameters_after_parsing(app, unit_cfg); +} + +bool split6_du_application_unit_impl::on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const { if (!plugin->on_configuration_validation()) { return false; } - return true; + return validate_split6_du_unit_config(unit_cfg, available_cpus); } void split6_du_application_unit_impl::on_parsing_configuration_registration(CLI::App& app) @@ -36,7 +46,7 @@ void split6_du_application_unit_impl::on_parsing_configuration_registration(CLI: plugin->on_parsing_configuration_registration(app); } -du_unit split6_du_application_unit_impl::create_unit(const du_unit_dependencies& dependencies) +du_unit split6_du_application_unit_impl::create_flexible_du_unit(const du_unit_dependencies& dependencies) { auto fapi_ctrl = plugin->create_fapi_adaptor(dependencies); report_error_if_not(!fapi_ctrl.empty(), "Could not create FAPI adaptor"); @@ -45,3 +55,18 @@ du_unit split6_du_application_unit_impl::create_unit(const du_unit_dependencies& return du_impl; } + +void split6_du_application_unit_impl::dump_config(YAML::Node& node) const +{ + fill_du_high_config_in_yaml_schema(node, unit_cfg.du_high_cfg.config); + fill_fapi_config_in_yaml_schema(node, unit_cfg.fapi_cfg); +} + +void split6_du_application_unit_impl::fill_worker_manager_config(worker_manager_config& config) +{ + // Split 6 always runs in non blocking mode. + bool is_blocking_mode_enable = false; + unsigned nof_cells = unit_cfg.du_high_cfg.config.cells_cfg.size(); + fill_du_high_worker_manager_config(config, unit_cfg.du_high_cfg.config, is_blocking_mode_enable); + fill_fapi_worker_manager_config(config, unit_cfg.fapi_cfg, nof_cells); +} diff --git a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.h b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.h index 1e9fd20bc0..7a62bab4c1 100644 --- a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.h +++ b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.h @@ -10,28 +10,40 @@ #pragma once -#include "apps/units/application_unit.h" -#include "apps/units/flexible_du/du_unit.h" +#include "apps/units/flexible_du/flexible_du_application_unit.h" #include "split6_du_unit_config.h" #include "split6_plugin.h" namespace srsran { /// DU Split6 application unit implementation. -class split6_du_application_unit_impl : public application_unit +class split6_du_application_unit_impl : public flexible_du_application_unit { public: // See interface for documentation. void on_parsing_configuration_registration(CLI::App& app) override; // See interface for documentation. - bool on_configuration_validation() const override; + void on_configuration_parameters_autoderivation(CLI::App& app) override; + + // See interface for documentation. + bool on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const override; // See interface for documentation. void on_loggers_registration() override; - /// Creates the DU unit. - du_unit create_unit(const du_unit_dependencies& dependencies); + // See interface for documentation. + du_unit create_flexible_du_unit(const du_unit_dependencies& dependencies) override; + + // See interface for documentation. + du_high_unit_config& get_du_high_unit_config() override { return unit_cfg.du_high_cfg.config; } + const du_high_unit_config& get_du_high_unit_config() const override { return unit_cfg.du_high_cfg.config; } + + // See interface for documentation. + void dump_config(YAML::Node& node) const override; + + // See interface for documentation. + void fill_worker_manager_config(worker_manager_config& config) override; private: split6_du_unit_config unit_cfg; diff --git a/apps/units/flexible_du/split_7_2/CMakeLists.txt b/apps/units/flexible_du/split_7_2/CMakeLists.txt index 5fa1151b0f..d1596233c3 100644 --- a/apps/units/flexible_du/split_7_2/CMakeLists.txt +++ b/apps/units/flexible_du/split_7_2/CMakeLists.txt @@ -6,17 +6,37 @@ # the distribution. # -if (DPDK_FOUND) - add_definitions(-DDPDK_FOUND) -endif (DPDK_FOUND) -set(SOURCES - ru_ofh_config_cli11_schema.cpp - ru_ofh_factories.cpp - ru_ofh_config_translator.cpp - ru_ofh_config_validator.cpp - ru_ofh_config_yaml_writer.cpp) +add_subdirectory(helpers) -add_library(srsran_split_7_2_app_unit_helpers STATIC ${SOURCES}) -target_link_libraries(srsran_split_7_2_app_unit_helpers srsran_ru_ofh srsran_flexible_du_helpers) -target_include_directories(srsran_split_7_2_app_unit_helpers PRIVATE ${CMAKE_SOURCE_DIR}) +# Build the flexible du split 7.2 library when it is selected in the definition. +if (DU_SPLIT_7_2) + set(SOURCES + split_7_2_du_application_unit_impl.cpp + split_7_2_du_factory.cpp + split_7_2_du_impl.cpp + split_7_2_du_unit_cli11_schema.cpp + split_7_2_du_unit_config_validator.cpp + split_7_2_du_unit_config_yaml_writer.cpp) + + add_library(srsran_flexible_du STATIC ${SOURCES}) + target_include_directories(srsran_flexible_du PRIVATE ${CMAKE_SOURCE_DIR}) + set(FLEXIBLE_DU_LIBRARIES + srsran_du_wrapper + srsran_pcap + srsran_app_services + srsran_fapi_app_unit + srsran_du_low_unit_helpers + srsran_split_7_2_app_unit_helpers + srsran_du_high_unit_helpers) + + # Hardware acceleration for both PUSCH and PDSCH is enabled by default when using DPDK. + if (DPDK_FOUND) + set_source_files_properties(split_7_2_du_factory.cpp PROPERTIES COMPILE_DEFINITIONS "DPDK_FOUND; HWACC_PDSCH_ENABLED; HWACC_PUSCH_ENABLED") + list(APPEND FLEXIBLE_DU_LIBRARIES hal_hwacc_pusch + hal_hwacc_pdsch + hal_bbdev_factory) + endif (DPDK_FOUND) + target_link_libraries(srsran_flexible_du ${FLEXIBLE_DU_LIBRARIES}) + +endif () diff --git a/apps/units/flexible_du/split_7_2/helpers/CMakeLists.txt b/apps/units/flexible_du/split_7_2/helpers/CMakeLists.txt new file mode 100644 index 0000000000..801de7609b --- /dev/null +++ b/apps/units/flexible_du/split_7_2/helpers/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +if (DPDK_FOUND) + add_definitions(-DDPDK_FOUND) +endif (DPDK_FOUND) + +set(SOURCES + ru_ofh_config_cli11_schema.cpp + ru_ofh_factories.cpp + ru_ofh_config_translator.cpp + ru_ofh_config_validator.cpp + ru_ofh_config_yaml_writer.cpp) + +add_library(srsran_split_7_2_app_unit_helpers STATIC ${SOURCES}) +target_link_libraries(srsran_split_7_2_app_unit_helpers srsran_ru_ofh srsran_flexible_du_helpers) +target_include_directories(srsran_split_7_2_app_unit_helpers PRIVATE ${CMAKE_SOURCE_DIR}) diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config.h b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config.h similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_config.h rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config.h diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_cli11_schema.cpp b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_cli11_schema.cpp similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_cli11_schema.cpp rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_cli11_schema.cpp diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_cli11_schema.h b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_cli11_schema.h similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_cli11_schema.h rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_cli11_schema.h diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.cpp b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp similarity index 85% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_translator.cpp rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp index eb96514907..bcc21de2e5 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.cpp +++ b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp @@ -9,6 +9,7 @@ */ #include "ru_ofh_config_translator.h" +#include "apps/services/worker_manager_config.h" #include "apps/units/flexible_du/du_high/du_high_config.h" #include "ru_ofh_config.h" #include "srsran/du/du_cell_config.h" @@ -152,3 +153,31 @@ ru_ofh_configuration srsran::generate_ru_ofh_config(const ru_ofh_unit_config& return out_cfg; } + +void srsran::fill_ofh_worker_manager_config(worker_manager_config& config, + const ru_ofh_unit_config& ru_cfg, + span du_cells) +{ + auto& ofh_cfg = config.ru_ofh_cfg.emplace(); + ofh_cfg.is_downlink_parallelized = ru_cfg.expert_execution_cfg.threads.is_downlink_parallelized; + for (const auto& du_cell : du_cells) { + ofh_cfg.nof_downlink_antennas.push_back(du_cell.dl_carrier.nof_ant); + } + ofh_cfg.ru_timing_cpu = ru_cfg.expert_execution_cfg.ru_timing_cpu; + ofh_cfg.txrx_affinities = ru_cfg.expert_execution_cfg.txrx_affinities; + + // If ru_txrx_cpus parameters are not specified, use the affinities of ru_cpus parameters of the cells. + if (ofh_cfg.txrx_affinities.empty()) { + for (unsigned i = 0, e = du_cells.size(); i != e; ++i) { + auto affinity_cfg = ru_cfg.expert_execution_cfg.cell_affinities[i].ru_cpu_cfg; + ofh_cfg.txrx_affinities.emplace_back(affinity_cfg.mask); + } + } + + srsran_assert(config.config_affinities.size() == ru_cfg.expert_execution_cfg.cell_affinities.size(), + "Invalid number of cell affinities"); + + for (unsigned i = 0, e = ru_cfg.expert_execution_cfg.cell_affinities.size(); i != e; ++i) { + config.config_affinities[i].push_back(ru_cfg.expert_execution_cfg.cell_affinities[i].ru_cpu_cfg); + } +} diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.h b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.h similarity index 69% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_translator.h rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.h index 19ff4c090c..84db048b0b 100644 --- a/apps/units/flexible_du/split_7_2/ru_ofh_config_translator.h +++ b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.h @@ -19,6 +19,7 @@ struct du_cell_config; } struct ru_ofh_unit_config; +struct worker_manager_config; /// Converts and returns the given Open Fronthaul Radio Unit application unit configuration to a Open Fronthaul Radio /// Unit configuration. @@ -26,4 +27,9 @@ ru_ofh_configuration generate_ru_ofh_config(const ru_ofh_unit_config& r span du_cells, unsigned max_processing_delay_slots); +/// Fills the OFH worker manager parameters of the given worker manager configuration. +void fill_ofh_worker_manager_config(worker_manager_config& config, + const ru_ofh_unit_config& ru_cfg, + span du_cells); + } // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_validator.cpp b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_validator.cpp similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_validator.cpp rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_validator.cpp diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_validator.h b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_validator.h similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_validator.h rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_validator.h diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.cpp b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_yaml_writer.cpp similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.cpp rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_yaml_writer.cpp diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.h b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_yaml_writer.h similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.h rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_yaml_writer.h diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_factories.cpp b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_factories.cpp similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_factories.cpp rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_factories.cpp diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_factories.h b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_factories.h similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_factories.h rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_factories.h diff --git a/apps/units/flexible_du/split_7_2/ru_ofh_logger_registrator.h b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_logger_registrator.h similarity index 100% rename from apps/units/flexible_du/split_7_2/ru_ofh_logger_registrator.h rename to apps/units/flexible_du/split_7_2/helpers/ru_ofh_logger_registrator.h diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.cpp b/apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.cpp new file mode 100644 index 0000000000..f3d27d2841 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.cpp @@ -0,0 +1,70 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_7_2_du_application_unit_impl.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/du_low/du_low_config_translator.h" +#include "apps/units/flexible_du/fapi/fapi_config_translator.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.h" +#include "split_7_2_du_factory.h" +#include "split_7_2_du_unit_cli11_schema.h" +#include "split_7_2_du_unit_config_validator.h" +#include "split_7_2_du_unit_config_yaml_writer.h" +#include "split_7_2_du_unit_logger_registrator.h" + +using namespace srsran; + +void split_7_2_du_application_unit_impl::on_loggers_registration() +{ + register_split_7_2_du_loggers(unit_cfg); +} + +void split_7_2_du_application_unit_impl::on_configuration_parameters_autoderivation(CLI::App& app) +{ + autoderive_split_7_2_du_parameters_after_parsing(app, unit_cfg); +} + +bool split_7_2_du_application_unit_impl::on_configuration_validation( + const os_sched_affinity_bitmask& available_cpus) const +{ + return validate_split_7_2_du_unit_config(unit_cfg, available_cpus); +} + +void split_7_2_du_application_unit_impl::on_parsing_configuration_registration(CLI::App& app) +{ + configure_cli11_with_split_7_2_du_unit_config_schema(app, unit_cfg); +} + +du_unit split_7_2_du_application_unit_impl::create_flexible_du_unit(const du_unit_dependencies& dependencies) +{ + return create_split_7_2_du(unit_cfg, dependencies); +} + +std::unique_ptr srsran::create_flexible_du_application_unit() +{ + return std::make_unique(); +} + +void split_7_2_du_application_unit_impl::dump_config(YAML::Node& node) const +{ + fill_split_7_2_du_unit_config_in_yaml_schema(node, unit_cfg); +} + +void split_7_2_du_application_unit_impl::fill_worker_manager_config(worker_manager_config& config) +{ + // OFH always runs in non blocking mode. + bool is_blocking_mode_enable = false; + unsigned nof_cells = unit_cfg.du_high_cfg.config.cells_cfg.size(); + fill_du_high_worker_manager_config(config, unit_cfg.du_high_cfg.config, is_blocking_mode_enable); + fill_du_low_worker_manager_config(config, unit_cfg.du_low_cfg, is_blocking_mode_enable, nof_cells); + fill_fapi_worker_manager_config(config, unit_cfg.fapi_cfg, nof_cells); + auto cells = generate_du_cell_config(unit_cfg.du_high_cfg.config); + fill_ofh_worker_manager_config(config, unit_cfg.ru_cfg.config, cells); +} diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.h b/apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.h new file mode 100644 index 0000000000..9d874c0b92 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_application_unit_impl.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/flexible_du_application_unit.h" +#include "split_7_2_du_unit_config.h" + +namespace srsran { + +/// Split 7.2 DU application unit implementation. +class split_7_2_du_application_unit_impl : public flexible_du_application_unit +{ +public: + // See interface for documentation. + void on_parsing_configuration_registration(CLI::App& app) override; + + // See interface for documentation. + void on_configuration_parameters_autoderivation(CLI::App& app) override; + + // See interface for documentation. + bool on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const override; + + // See interface for documentation. + void on_loggers_registration() override; + + // See interface for documentation. + du_unit create_flexible_du_unit(const du_unit_dependencies& dependencies) override; + + // See interface for documentation. + du_high_unit_config& get_du_high_unit_config() override { return unit_cfg.du_high_cfg.config; } + const du_high_unit_config& get_du_high_unit_config() const override { return unit_cfg.du_high_cfg.config; } + + // See interface for documentation. + void dump_config(YAML::Node& node) const override; + + // See interface for documentation. + void fill_worker_manager_config(worker_manager_config& config) override; + +private: + split_7_2_du_unit_config unit_cfg; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_factory.cpp b/apps/units/flexible_du/split_7_2/split_7_2_du_factory.cpp new file mode 100644 index 0000000000..eb37314aa3 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_factory.cpp @@ -0,0 +1,263 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_7_2_du_factory.h" +#include "apps/services/e2_metric_connector_manager.h" +#include "apps/services/worker_manager.h" +#include "apps/units/flexible_du/du_high/du_high_commands.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h" +#include "apps/units/flexible_du/du_low/du_low_config_translator.h" +#include "apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h" +#include "apps/units/flexible_du/flexible_du_commands.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_factories.h" +#include "split_7_2_du_impl.h" +#include "srsran/du/du_wrapper.h" +#include "srsran/du/du_wrapper_factory.h" +#include "srsran/pcap/rlc_pcap.h" +#include "srsran/ru/ru_dummy_factory.h" +#ifdef DPDK_FOUND +#include "srsran/hal/dpdk/bbdev/bbdev_acc.h" +#include "srsran/hal/dpdk/bbdev/bbdev_acc_factory.h" +#include "srsran/hal/phy/upper/channel_processors/hw_accelerator_factories.h" +#include "srsran/hal/phy/upper/channel_processors/pusch/ext_harq_buffer_context_repository_factory.h" +#include "srsran/hal/phy/upper/channel_processors/pusch/hw_accelerator_factories.h" +#endif // DPDK_FOUND + +using namespace srsran; + +static std::unique_ptr create_radio_unit(const ru_ofh_unit_config& ru_cfg, + worker_manager& workers, + span du_cells, + ru_uplink_plane_rx_symbol_notifier& symbol_notifier, + ru_timing_notifier& timing_notifier, + ru_error_notifier& error_notifier, + unsigned max_processing_delay) +{ + ru_ofh_factory_config config; + config.ru_cfg = ru_cfg; + config.max_processing_delay_slots = max_processing_delay; + config.du_cells = du_cells; + + ru_ofh_factory_dependencies dependencies; + dependencies.workers = &workers; + dependencies.error_notifier = &error_notifier; + dependencies.symbol_notifier = &symbol_notifier; + dependencies.timing_notifier = &timing_notifier; + + return create_ofh_radio_unit(config, dependencies); +} + +/// \brief Update the Flexible DU metrics configuration with the given local DU configuration and E2 configuration. +/// +/// This function manages the multi cell workaround for the DU high metrics. To have multi cell, now one DU is +/// instantiated per cell, so this would create multiple consumers that does not make sense, for example stdout. +/// With this we avoid having 2 different objects that write in the stdout. +static void update_du_metrics(std::vector& flexible_du_cfg, + std::vector local_du_cfg, + bool is_e2_enabled) +{ + // First call, copy everything. + if (flexible_du_cfg.empty()) { + flexible_du_cfg = std::move(local_du_cfg); + return; + } + + // Safe check that all the DUs provides the same amount of metrics. + srsran_assert(flexible_du_cfg.size() == local_du_cfg.size(), + "Flexible DU metrics size '{}' does not match DU metrics size '{}'", + flexible_du_cfg.size(), + local_du_cfg.size()); + + // Iterate the metrics configs of each DU. Each DU should ha + for (unsigned i = 0, e = local_du_cfg.size(); i != e; ++i) { + // Store the metrics producers for each DU. + flexible_du_cfg[i].producers.push_back(std::move(local_du_cfg[i].producers.back())); + + // Move E2 consumers for each DU to the common output config. E2 Consumers occupy the last position. + if (is_e2_enabled) { + flexible_du_cfg[i].consumers.push_back(std::move(local_du_cfg[i].consumers.back())); + } + } +} + +du_unit srsran::create_split_7_2_du(const split_7_2_du_unit_config& du_72_cfg, const du_unit_dependencies& dependencies) +{ + du_unit du_cmd_wrapper; + + const du_high_unit_config& du_hi = du_72_cfg.du_high_cfg.config; + const du_low_unit_config& du_lo = du_72_cfg.du_low_cfg; + const fapi_unit_config& fapi_cfg = du_72_cfg.fapi_cfg; + + auto du_cells = generate_du_cell_config(du_hi); + + std::vector> du_insts; + auto du_impl = std::make_unique(du_cells.size()); + + std::vector prach_ports; + std::vector max_pusch_per_slot; + for (const auto& high : du_hi.cells_cfg) { + prach_ports.push_back(high.cell.prach_cfg.ports); + max_pusch_per_slot.push_back(high.cell.pusch_cfg.max_puschs_per_slot); + } + + // Initialize hardware-accelerator (only if needed). + hal_upper_phy_config hal_config = {}; + hal_config.hwacc_pdsch_processor = false; + hal_config.hwacc_pusch_processor = false; +#ifdef DPDK_FOUND + hal::bbdev_hwacc_pdsch_enc_factory_configuration hwacc_pdsch_enc_cfg = {}; + hal::bbdev_hwacc_pusch_dec_factory_configuration hwacc_pusch_dec_cfg = {}; + std::shared_ptr harq_buffer_context = nullptr; + unsigned nof_hwacc_dus = du_cells.size(); + if (!du_lo.hal_config->bbdev_hwacc->hwacc_type.empty()) { + srslog::basic_logger& hwacc_logger = srslog::fetch_basic_logger("HWACC", false); + hwacc_logger.set_level(du_lo.loggers.hal_level); + + // Create a bbdev accelerator factory. + std::unique_ptr bbdev_acc_factory = + srsran::dpdk::create_bbdev_acc_factory(du_lo.hal_config->bbdev_hwacc->bbdev_acc_type); + report_error_if_not(bbdev_acc_factory, + "Unable to create the {} bbdev hardware-accelerator interface factory.", + du_lo.hal_config->bbdev_hwacc->bbdev_acc_type); + + // Intefacing to the bbdev-based hardware-accelerator. + dpdk::bbdev_acc_configuration bbdev_config; + bbdev_config.id = du_lo.hal_config->bbdev_hwacc->id; + if (du_lo.hal_config->bbdev_hwacc->pdsch_enc->nof_hwacc > 0) { + bbdev_config.nof_ldpc_enc_lcores = nof_hwacc_dus * du_lo.hal_config->bbdev_hwacc->pdsch_enc->nof_hwacc; + } + if (du_lo.hal_config->bbdev_hwacc->pusch_dec->nof_hwacc > 0) { + bbdev_config.nof_ldpc_dec_lcores = nof_hwacc_dus * du_lo.hal_config->bbdev_hwacc->pusch_dec->nof_hwacc; + } + // If no msg_mbuf size is defined, a worst-case value will be used. + bbdev_config.msg_mbuf_size = du_lo.hal_config->bbdev_hwacc->msg_mbuf_size.value_or(RTE_BBDEV_LDPC_E_MAX_MBUF); + // If no rm_mbuf size is defined, a worst-case value will be used. + bbdev_config.rm_mbuf_size = du_lo.hal_config->bbdev_hwacc->rm_mbuf_size.value_or(RTE_BBDEV_LDPC_E_MAX_MBUF); + // If no number of mbufs is defined, a worst-case value will be used. + bbdev_config.nof_mbuf = + du_lo.hal_config->bbdev_hwacc->nof_mbuf.value_or(static_cast(pow2(log2_ceil(MAX_NOF_SEGMENTS)))); + std::shared_ptr bbdev_accelerator = bbdev_acc_factory->create(bbdev_config, hwacc_logger); + report_error_if_not( + bbdev_accelerator, "Unable to open the {} hardware-accelerator.", du_lo.hal_config->bbdev_hwacc->hwacc_type); + + // Configure the hardware-accelerated PDSCH encoding factory (only if needed). + if (du_lo.hal_config->bbdev_hwacc->pdsch_enc->nof_hwacc > 0) { + hwacc_pdsch_enc_cfg.acc_type = du_lo.hal_config->bbdev_hwacc->hwacc_type; + hwacc_pdsch_enc_cfg.bbdev_accelerator = bbdev_accelerator; + hwacc_pdsch_enc_cfg.cb_mode = du_lo.hal_config->bbdev_hwacc->pdsch_enc->cb_mode; + // If no maximum buffer size is defined, a worst-case value will be used. + hwacc_pdsch_enc_cfg.max_tb_size = + du_lo.hal_config->bbdev_hwacc->pdsch_enc->max_buffer_size.value_or(RTE_BBDEV_LDPC_E_MAX_MBUF); + hwacc_pdsch_enc_cfg.dedicated_queue = du_lo.hal_config->bbdev_hwacc->pdsch_enc->dedicated_queue; + hal_config.hwacc_pdsch_processor = true; + hal_config.hwacc_pdsch_enc_cfg = hwacc_pdsch_enc_cfg; + } + + // Configure the hardware-accelerated PUSCH decoding factory (only if needed). + if (du_lo.hal_config->bbdev_hwacc->pusch_dec->nof_hwacc > 0) { + hwacc_pusch_dec_cfg.acc_type = du_lo.hal_config->bbdev_hwacc->hwacc_type; + hwacc_pusch_dec_cfg.bbdev_accelerator = bbdev_accelerator; + hwacc_pusch_dec_cfg.ext_softbuffer = du_lo.hal_config->bbdev_hwacc->pusch_dec->ext_softbuffer; + if (hwacc_pusch_dec_cfg.ext_softbuffer) { + // Set up an external HARQ buffer context repository. + unsigned nof_cbs = du_lo.hal_config->bbdev_hwacc->pusch_dec->harq_context_size.value_or(MAX_NOF_SEGMENTS); + uint64_t ext_harq_buff_size = bbdev_accelerator->get_harq_buff_size_bytes(); + harq_buffer_context = hal::create_ext_harq_buffer_context_repository(nof_cbs, ext_harq_buff_size, false); + report_error_if_not(harq_buffer_context, + "Unable to create the external HARQ buffer context for the {} hardware-accelerator.", + du_lo.hal_config->bbdev_hwacc->hwacc_type); + hwacc_pusch_dec_cfg.harq_buffer_context = harq_buffer_context; + } + hwacc_pusch_dec_cfg.dedicated_queue = du_lo.hal_config->bbdev_hwacc->pusch_dec->dedicated_queue; + hal_config.hwacc_pusch_processor = true; + hal_config.hwacc_pusch_dec_cfg = hwacc_pusch_dec_cfg; + } + } +#endif // DPDK_FOUND + + for (unsigned i = 0, e = du_cells.size(); i != e; ++i) { + // Create one DU per cell. + srs_du::du_wrapper_config du_cfg = {}; + du_high_unit_config tmp_cfg = du_hi; + tmp_cfg.cells_cfg.resize(1); + tmp_cfg.cells_cfg[0] = du_hi.cells_cfg[i]; + + make_du_low_wrapper_config_and_dependencies(du_cfg.du_low_cfg, + du_lo, + hal_config, + {prach_ports[i]}, + span(&du_cells[i], 1), + span(&max_pusch_per_slot[i], 1), + du_impl->get_upper_ru_dl_rg_adapter(), + du_impl->get_upper_ru_ul_request_adapter(), + *dependencies.workers, + i); + + auto cell_services_cfg = fill_du_high_wrapper_config(du_cfg.du_high_cfg, + tmp_cfg, + i, + dependencies.workers->get_du_high_executor_mapper(i), + *dependencies.f1c_client_handler, + *dependencies.f1u_gw, + *dependencies.timer_mng, + *dependencies.mac_p, + *dependencies.rlc_p, + *dependencies.e2_client_handler, + *dependencies.e2_metric_connectors, + *dependencies.json_sink, + *dependencies.metrics_notifier); + + update_du_metrics(du_cmd_wrapper.metrics, std::move(cell_services_cfg.first), tmp_cfg.e2_cfg.enable_du_e2); + + // Use the commands of the first cell. + if (i == 0) { + for (auto& command : cell_services_cfg.second) + du_cmd_wrapper.commands.push_back(std::move(command)); + } + + // FAPI configuration. + du_cfg.du_high_cfg.fapi.log_level = fapi_cfg.fapi_level; + if (fapi_cfg.l2_nof_slots_ahead != 0) { + // As the temporal configuration contains only one cell, pick the data from that cell. + du_cfg.du_high_cfg.fapi.l2_nof_slots_ahead = fapi_cfg.l2_nof_slots_ahead; + du_cfg.du_high_cfg.fapi.executor.emplace(dependencies.workers->fapi_exec[i]); + } + + du_insts.push_back(make_du_wrapper(du_cfg)); + report_error_if_not(du_insts.back(), "Invalid Distributed Unit"); + } + + std::unique_ptr ru = create_radio_unit(du_72_cfg.ru_cfg.config, + *dependencies.workers, + du_cells, + du_impl->get_upper_ru_ul_adapter(), + du_impl->get_upper_ru_timing_adapter(), + du_impl->get_upper_ru_error_adapter(), + du_lo.expert_phy_cfg.max_processing_delay_slots); + + srsran_assert(ru, "Invalid Radio Unit"); + + // Add RU commands. + du_cmd_wrapper.commands.push_back(std::make_unique()); + du_cmd_wrapper.commands.push_back(std::make_unique(ru->get_controller())); + du_cmd_wrapper.commands.push_back(std::make_unique(ru->get_controller())); + du_cmd_wrapper.commands.push_back(std::make_unique(ru->get_controller())); + + du_impl->add_ru(std::move(ru)); + du_impl->add_dus(std::move(du_insts)); + + du_cmd_wrapper.unit = std::move(du_impl); + + // Configure the application unit metrics for the DU high. + announce_du_high_cells(du_hi); + + return du_cmd_wrapper; +} diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_factory.h b/apps/units/flexible_du/split_7_2/split_7_2_du_factory.h new file mode 100644 index 0000000000..7b1eddb8fd --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_factory.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_unit.h" +#include "split_7_2_du_unit_config.h" + +namespace srsran { + +namespace app_services { +class metrics_notifier; +} + +class e2_connection_client; +class e2_metric_connector_manager; +class f1ap_message_notifier; +class console_helper; +class metrics_log_helper; +class metrics_plotter_json; +class metrics_plotter_stdout; +class mac_pcap; +class timer_manager; +class upper_phy_rg_gateway; +class upper_phy_rx_symbol_request_notifier; + +namespace srs_du { +class f1c_connection_client; +class f1u_du_gateway; +} // namespace srs_du + +du_unit create_split_7_2_du(const split_7_2_du_unit_config& du_72_cfg, const du_unit_dependencies& dependencies); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_impl.cpp b/apps/units/flexible_du/split_7_2/split_7_2_du_impl.cpp new file mode 100644 index 0000000000..eaa30b0fd8 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_impl.cpp @@ -0,0 +1,67 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_7_2_du_impl.h" +#include "srsran/du/du_low/du_low.h" +#include "srsran/du/du_low/du_low_wrapper.h" +#include "srsran/du/du_wrapper.h" +#include "srsran/phy/upper/upper_phy.h" +#include "srsran/ru/ru.h" +#include "srsran/ru/ru_controller.h" + +using namespace srsran; + +split_7_2_du_impl::split_7_2_du_impl(unsigned nof_cells) : + ru_ul_adapt(nof_cells), ru_timing_adapt(nof_cells), ru_error_adapt(nof_cells) +{ +} + +void split_7_2_du_impl::start() +{ + for (auto& du_obj : du_list) { + du_obj->get_power_controller().start(); + } + + ru->get_controller().start(); +} + +void split_7_2_du_impl::stop() +{ + ru->get_controller().stop(); + + for (auto& du_obj : du_list) { + du_obj->get_power_controller().stop(); + } +} + +void split_7_2_du_impl::add_ru(std::unique_ptr active_ru) +{ + ru = std::move(active_ru); + srsran_assert(ru, "Invalid Radio Unit"); + + ru_dl_rg_adapt.connect(ru->get_downlink_plane_handler()); + ru_ul_request_adapt.connect(ru->get_uplink_plane_handler()); +} + +void split_7_2_du_impl::add_dus(std::vector> active_du) +{ + du_list = std::move(active_du); + srsran_assert(!du_list.empty(), "Cannot set an empty DU list"); + + for (auto& du_obj : du_list) { + span upper_ptrs = du_obj->get_du_low_wrapper().get_du_low().get_all_upper_phys(); + for (auto* upper : upper_ptrs) { + // Make connections between DU and RU. + ru_ul_adapt.map_handler(upper->get_sector_id(), upper->get_rx_symbol_handler()); + ru_timing_adapt.map_handler(upper->get_sector_id(), upper->get_timing_handler()); + ru_error_adapt.map_handler(upper->get_sector_id(), upper->get_error_handler()); + } + } +} diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_impl.h b/apps/units/flexible_du/split_7_2/split_7_2_du_impl.h new file mode 100644 index 0000000000..6cedccef18 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_impl.h @@ -0,0 +1,62 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/du/du.h" +#include "srsran/du/du_power_controller.h" +#include "srsran/du/du_wrapper.h" +#include "srsran/ru/ru_adapters.h" +#include +#include + +namespace srsran { + +class radio_unit; + +/// DU split 7.2 implementation. +class split_7_2_du_impl : public srs_du::du, public du_power_controller +{ +public: + explicit split_7_2_du_impl(unsigned nof_cells); + + // See interface for documentation. + du_power_controller& get_power_controller() override { return *this; } + + // See interface for documentation. + void start() override; + + // See interface for documentation. + void stop() override; + + /// Adds the given RU to this split 7.2 DU. + void add_ru(std::unique_ptr active_ru); + + /// Adds the given DUs to this split 7.2 DU. + void add_dus(std::vector> active_du); + + /// Getters to the adaptors. + upper_ru_ul_adapter& get_upper_ru_ul_adapter() { return ru_ul_adapt; } + upper_ru_timing_adapter& get_upper_ru_timing_adapter() { return ru_timing_adapt; } + upper_ru_error_adapter& get_upper_ru_error_adapter() { return ru_error_adapt; } + upper_ru_dl_rg_adapter& get_upper_ru_dl_rg_adapter() { return ru_dl_rg_adapt; } + upper_ru_ul_request_adapter& get_upper_ru_ul_request_adapter() { return ru_ul_request_adapt; } + +private: + upper_ru_ul_adapter ru_ul_adapt; + upper_ru_timing_adapter ru_timing_adapt; + upper_ru_error_adapter ru_error_adapt; + std::vector> du_list; + std::unique_ptr ru; + upper_ru_dl_rg_adapter ru_dl_rg_adapt; + upper_ru_ul_request_adapter ru_ul_request_adapt; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.cpp b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.cpp new file mode 100644 index 0000000000..596c3c4fef --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.cpp @@ -0,0 +1,46 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_7_2_du_unit_cli11_schema.h" +#include "apps/units/flexible_du/du_high/du_high_config_cli11_schema.h" +#include "apps/units/flexible_du/du_low/du_low_config_cli11_schema.h" +#include "apps/units/flexible_du/fapi/fapi_config_cli11_schema.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_cli11_schema.h" +#include "apps/units/flexible_du/support/cli11_cpu_affinities_parser_helper.h" +#include "split_7_2_du_unit_config.h" +#include "srsran/support/cli11_utils.h" +#include "srsran/support/config_parsers.h" + +using namespace srsran; + +void srsran::configure_cli11_with_split_7_2_du_unit_config_schema(CLI::App& app, split_7_2_du_unit_config& parsed_cfg) +{ + configure_cli11_with_du_high_config_schema(app, parsed_cfg.du_high_cfg); + configure_cli11_with_du_low_config_schema(app, parsed_cfg.du_low_cfg); + configure_cli11_with_fapi_config_schema(app, parsed_cfg.fapi_cfg); + configure_cli11_with_ru_ofh_config_schema(app, parsed_cfg.ru_cfg); +} + +void srsran::autoderive_split_7_2_du_parameters_after_parsing(CLI::App& app, split_7_2_du_unit_config& parsed_cfg) +{ + autoderive_du_high_parameters_after_parsing(app, parsed_cfg.du_high_cfg.config); + // Auto derive OFH parameters. + autoderive_ru_ofh_parameters_after_parsing(app, parsed_cfg.ru_cfg); + + // Auto derive DU low parameters. Split 7.2 does not use blocking mode. + const auto& cell = parsed_cfg.du_high_cfg.config.cells_cfg.front().cell; + nr_band band = cell.band ? cell.band.value() : band_helper::get_band_from_dl_arfcn(cell.dl_f_ref_arfcn); + bool is_blocking_mode_enabled = false; + autoderive_du_low_parameters_after_parsing(app, + parsed_cfg.du_low_cfg, + band_helper::get_duplex_mode(band), + is_blocking_mode_enabled, + parsed_cfg.du_high_cfg.config.cells_cfg.size()); +} diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.h b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.h new file mode 100644 index 0000000000..0c0164a423 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_cli11_schema.h @@ -0,0 +1,25 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "CLI/CLI11.hpp" + +namespace srsran { + +struct split_7_2_du_unit_config; + +/// Configures the given CLI11 application with the split 7.2 DU unit configuration schema. +void configure_cli11_with_split_7_2_du_unit_config_schema(CLI::App& app, split_7_2_du_unit_config& parsed_cfg); + +/// Auto derive split 7.2 DU parameters after the parsing. +void autoderive_split_7_2_du_parameters_after_parsing(CLI::App& app, split_7_2_du_unit_config& parsed_cfg); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config.h b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config.h new file mode 100644 index 0000000000..e957616fdc --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config.h @@ -0,0 +1,32 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_high/du_high_config.h" +#include "apps/units/flexible_du/du_low/du_low_config.h" +#include "apps/units/flexible_du/fapi/fapi_config.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config.h" + +namespace srsran { + +/// Split 7.2 DU unit configuration. +struct split_7_2_du_unit_config { + /// DU high configuration. + du_high_parsed_config du_high_cfg; + /// DU low configuration. + du_low_unit_config du_low_cfg; + /// FAPI configuration. + fapi_unit_config fapi_cfg; + /// Radio Unit configuration. + ru_ofh_unit_parsed_config ru_cfg; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.cpp b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.cpp new file mode 100644 index 0000000000..5420bc5051 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.cpp @@ -0,0 +1,84 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_7_2_du_unit_config_validator.h" +#include "apps/units/flexible_du/du_high/du_high_config_validator.h" +#include "apps/units/flexible_du/du_low/du_low_config_validator.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_validator.h" +#include "srsran/ran/prach/prach_configuration.h" +#include "srsran/ran/prach/prach_preamble_information.h" + +using namespace srsran; + +static std::vector get_du_low_validation_dependencies(const du_high_unit_config& config) +{ + std::vector out_cfg(config.cells_cfg.size()); + + for (unsigned i = 0, e = config.cells_cfg.size(); i != e; ++i) { + du_low_prach_validation_config& out_cell = out_cfg[i]; + const du_high_unit_base_cell_config& in_cell = config.cells_cfg[i].cell; + + // Get PRACH info. + subcarrier_spacing common_scs = in_cell.common_scs; + prach_configuration prach_info = prach_configuration_get(frequency_range::FR1, + band_helper::get_duplex_mode(in_cell.band.value()), + in_cell.prach_cfg.prach_config_index.value()); + + // PRACH format type. + out_cell.format = prach_info.format; + + // Get preamble info. + prach_preamble_information preamble_info = + is_long_preamble(prach_info.format) + ? get_prach_preamble_long_info(prach_info.format) + : get_prach_preamble_short_info(prach_info.format, to_ra_subcarrier_spacing(common_scs), false); + + out_cell.prach_scs = preamble_info.scs; + out_cell.zero_correlation_zone = in_cell.prach_cfg.zero_correlation_zone; + out_cell.nof_prach_ports = in_cell.prach_cfg.ports.size(); + out_cell.nof_antennas_ul = in_cell.nof_antennas_ul; + } + + return out_cfg; +} + +static std::vector get_ru_ofh_validation_dependencies(const du_high_unit_config& config) +{ + std::vector out_cfg(config.cells_cfg.size()); + + for (unsigned i = 0, e = config.cells_cfg.size(); i != e; ++i) { + ru_ofh_cell_validation_config& out_cell = out_cfg[i]; + const du_high_unit_base_cell_config& in_cell = config.cells_cfg[i].cell; + + // Validates the sampling rate is compatible with the PRACH sequence. + out_cell.scs = in_cell.common_scs; + out_cell.nof_prach_ports = in_cell.prach_cfg.ports.size(); + out_cell.nof_antennas_dl = in_cell.nof_antennas_dl; + out_cell.nof_antennas_ul = in_cell.nof_antennas_ul; + } + + return out_cfg; +} + +bool srsran::validate_split_7_2_du_unit_config(const split_7_2_du_unit_config& config, + const os_sched_affinity_bitmask& available_cpus) +{ + if (!validate_du_high_config(config.du_high_cfg.config, available_cpus)) { + return false; + } + + auto du_low_dependencies = get_du_low_validation_dependencies(config.du_high_cfg.config); + if (!validate_du_low_config(config.du_low_cfg, du_low_dependencies, available_cpus)) { + return false; + } + + auto ru_ofh_dependencies = get_ru_ofh_validation_dependencies(config.du_high_cfg.config); + return validate_ru_ofh_config(config.ru_cfg.config, ru_ofh_dependencies, available_cpus); +} diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.h b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.h new file mode 100644 index 0000000000..354f230929 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_validator.h @@ -0,0 +1,21 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "split_7_2_du_unit_config.h" + +namespace srsran { + +/// Validates the given split 7.2 DU unit configuration. Returns true on success, false otherwise. +bool validate_split_7_2_du_unit_config(const split_7_2_du_unit_config& config, + const os_sched_affinity_bitmask& available_cpus); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.cpp b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.cpp new file mode 100644 index 0000000000..da9f84ab64 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.cpp @@ -0,0 +1,26 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_7_2_du_unit_config_yaml_writer.h" +#include "apps/units/flexible_du/du_high/du_high_config_yaml_writer.h" +#include "apps/units/flexible_du/du_low/du_low_config_yaml_writer.h" +#include "apps/units/flexible_du/fapi/fapi_config_yaml_writer.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_yaml_writer.h" +#include "split_7_2_du_unit_config.h" + +using namespace srsran; + +void srsran::fill_split_7_2_du_unit_config_in_yaml_schema(YAML::Node& node, const split_7_2_du_unit_config& config) +{ + fill_du_high_config_in_yaml_schema(node, config.du_high_cfg.config); + fill_du_low_config_in_yaml_schema(node, config.du_low_cfg); + fill_fapi_config_in_yaml_schema(node, config.fapi_cfg); + fill_ru_ofh_config_in_yaml_schema(node, config.ru_cfg.config); +} diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.h b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.h new file mode 100644 index 0000000000..6c7e4d9176 --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_config_yaml_writer.h @@ -0,0 +1,22 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include + +namespace srsran { + +struct split_7_2_du_unit_config; + +/// Fills the given node with the split 7.2 DU configuration values. +void fill_split_7_2_du_unit_config_in_yaml_schema(YAML::Node& node, const split_7_2_du_unit_config& config); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_7_2/split_7_2_du_unit_logger_registrator.h b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_logger_registrator.h new file mode 100644 index 0000000000..c7b8cfd36a --- /dev/null +++ b/apps/units/flexible_du/split_7_2/split_7_2_du_unit_logger_registrator.h @@ -0,0 +1,30 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_high/du_high_logger_registrator.h" +#include "apps/units/flexible_du/du_low/du_low_logger_registrator.h" +#include "apps/units/flexible_du/fapi/fapi_logger_registrator.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_logger_registrator.h" +#include "split_7_2_du_unit_config.h" + +namespace srsran { + +/// Registers all the loggers for the DU split 7.2. +inline void register_split_7_2_du_loggers(const split_7_2_du_unit_config& config) +{ + register_du_high_loggers(config.du_high_cfg.config.loggers); + register_du_low_loggers(config.du_low_cfg.loggers); + register_fapi_loggers(config.fapi_cfg); + register_ru_ofh_loggers(config.ru_cfg.config.loggers); +} + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp b/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp index a10ed25670..7e4ed7a2f4 100644 --- a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp +++ b/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp @@ -9,6 +9,7 @@ */ #include "ru_sdr_config_translator.h" +#include "apps/services/worker_manager_config.h" #include "apps/units/flexible_du/du_high/du_high_config.h" #include "apps/units/flexible_du/du_low/du_low_config.h" #include "ru_sdr_config.h" @@ -257,3 +258,21 @@ ru_generic_configuration srsran::generate_ru_sdr_config(const ru_sdr_unit_config return out_cfg; } + +void srsran::fill_sdr_worker_manager_config(worker_manager_config& config, const ru_sdr_unit_config& ru_cfg) +{ + auto& sdr_cfg = config.ru_sdr_cfg.emplace(); + + sdr_cfg.nof_cells = ru_cfg.expert_execution_cfg.cell_affinities.size(); + sdr_cfg.profile = (ru_cfg.device_driver != "zmq") + ? static_cast( + ru_cfg.expert_execution_cfg.threads.execution_profile) + : worker_manager_config::ru_sdr_config::lower_phy_thread_profile::blocking; + + srsran_assert(config.config_affinities.size() == ru_cfg.expert_execution_cfg.cell_affinities.size(), + "Invalid number of cell affinities"); + + for (unsigned i = 0; i != sdr_cfg.nof_cells; ++i) { + config.config_affinities[i].push_back(ru_cfg.expert_execution_cfg.cell_affinities[i].ru_cpu_cfg); + } +} diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_translator.h b/apps/units/flexible_du/split_8/ru_sdr_config_translator.h index 3f200b80d8..e43bd614cd 100644 --- a/apps/units/flexible_du/split_8/ru_sdr_config_translator.h +++ b/apps/units/flexible_du/split_8/ru_sdr_config_translator.h @@ -17,11 +17,16 @@ namespace srsran { namespace srs_du { struct du_cell_config; } + struct ru_sdr_unit_config; +struct worker_manager_config; /// Converts and returns the given RU SDR application unit configuration to a SDR RU configuration. ru_generic_configuration generate_ru_sdr_config(const ru_sdr_unit_config& ru_cfg, span du_cells, unsigned max_processing_delay_slots); +/// Fills the SDR worker manager parameters of the given worker manager configuration. +void fill_sdr_worker_manager_config(worker_manager_config& config, const ru_sdr_unit_config& ru_cfg); + } // namespace srsran diff --git a/apps/units/flexible_du/split_dynamic/CMakeLists.txt b/apps/units/flexible_du/split_dynamic/CMakeLists.txt index 95f0fcd171..7b2b8630af 100644 --- a/apps/units/flexible_du/split_dynamic/CMakeLists.txt +++ b/apps/units/flexible_du/split_dynamic/CMakeLists.txt @@ -15,9 +15,9 @@ set(SOURCES dynamic_du_unit_config_validator.cpp dynamic_du_unit_config_yaml_writer.cpp) -add_library(srsran_flexible_du_dynamic STATIC ${SOURCES}) -target_include_directories(srsran_flexible_du_dynamic PRIVATE ${CMAKE_SOURCE_DIR}) -set(FLEXIBLE_DU_DYNAMIC_LIBRARIES +add_library(srsran_flexible_du STATIC ${SOURCES}) +target_include_directories(srsran_flexible_du PRIVATE ${CMAKE_SOURCE_DIR}) +set(FLEXIBLE_DU_LIBRARIES srsran_du_wrapper srsran_ru_dummy srsran_pcap @@ -31,8 +31,8 @@ set(FLEXIBLE_DU_DYNAMIC_LIBRARIES # Hardware acceleration for both PUSCH and PDSCH is enabled by default when using DPDK. if (DPDK_FOUND) set_source_files_properties(dynamic_du_factory.cpp PROPERTIES COMPILE_DEFINITIONS "DPDK_FOUND; HWACC_PDSCH_ENABLED; HWACC_PUSCH_ENABLED") - list(APPEND FLEXIBLE_DU_DYNAMIC_LIBRARIES hal_hwacc_pusch + list(APPEND FLEXIBLE_DU_LIBRARIES hal_hwacc_pusch hal_hwacc_pdsch hal_bbdev_factory) endif (DPDK_FOUND) -target_link_libraries(srsran_flexible_du_dynamic ${FLEXIBLE_DU_DYNAMIC_LIBRARIES}) +target_link_libraries(srsran_flexible_du ${FLEXIBLE_DU_LIBRARIES}) diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.cpp index 2250c13ee7..e8f5f3d56a 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.cpp @@ -9,7 +9,11 @@ */ #include "dynamic_du_application_unit_impl.h" +#include "dynamic_du_factory.h" +#include "dynamic_du_translators.h" #include "dynamic_du_unit_cli11_schema.h" +#include "dynamic_du_unit_config_validator.h" +#include "dynamic_du_unit_config_yaml_writer.h" #include "dynamic_du_unit_logger_registrator.h" using namespace srsran; @@ -19,12 +23,38 @@ void dynamic_du_application_unit_impl::on_loggers_registration() register_dynamic_du_loggers(unit_cfg); } -bool dynamic_du_application_unit_impl::on_configuration_validation() const +void dynamic_du_application_unit_impl::on_configuration_parameters_autoderivation(CLI::App& app) { - return false; + autoderive_dynamic_du_parameters_after_parsing(app, unit_cfg); +} + +bool dynamic_du_application_unit_impl::on_configuration_validation( + const os_sched_affinity_bitmask& available_cpus) const +{ + return validate_dynamic_du_unit_config(unit_cfg, available_cpus); } void dynamic_du_application_unit_impl::on_parsing_configuration_registration(CLI::App& app) { configure_cli11_with_dynamic_du_unit_config_schema(app, unit_cfg); } + +du_unit dynamic_du_application_unit_impl::create_flexible_du_unit(const du_unit_dependencies& dependencies) +{ + return create_dynamic_du(unit_cfg, dependencies); +} + +std::unique_ptr srsran::create_flexible_du_application_unit() +{ + return std::make_unique(); +} + +void dynamic_du_application_unit_impl::dump_config(YAML::Node& node) const +{ + fill_dynamic_du_unit_config_in_yaml_schema(node, unit_cfg); +} + +void dynamic_du_application_unit_impl::fill_worker_manager_config(worker_manager_config& config) +{ + fill_dynamic_du_worker_manager_config(config, unit_cfg); +} diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.h b/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.h index 2e4dffc2a1..fee4136424 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_application_unit_impl.h @@ -10,7 +10,7 @@ #pragma once -#include "apps/units/application_unit.h" +#include "apps/units/flexible_du/flexible_du_application_unit.h" #include "dynamic_du_unit_config.h" namespace srsran { @@ -18,18 +18,34 @@ namespace srsran { /// \brief Dynamic DU application unit implementation. /// /// A DU of type Dynamic adds support to all the types of Radio Units. -class dynamic_du_application_unit_impl : public application_unit +class dynamic_du_application_unit_impl : public flexible_du_application_unit { public: // See interface for documentation. void on_parsing_configuration_registration(CLI::App& app) override; // See interface for documentation. - bool on_configuration_validation() const override; + void on_configuration_parameters_autoderivation(CLI::App& app) override; + + // See interface for documentation. + bool on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const override; // See interface for documentation. void on_loggers_registration() override; + // See interface for documentation. + du_unit create_flexible_du_unit(const du_unit_dependencies& dependencies) override; + + // See interface for documentation. + du_high_unit_config& get_du_high_unit_config() override { return unit_cfg.du_high_cfg.config; } + const du_high_unit_config& get_du_high_unit_config() const override { return unit_cfg.du_high_cfg.config; } + + // See interface for documentation. + void dump_config(YAML::Node& node) const override; + + // See interface for documentation. + void fill_worker_manager_config(worker_manager_config& config) override; + private: dynamic_du_unit_config unit_cfg; }; diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp index 65a606fff6..8edaf9704d 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp @@ -10,16 +10,19 @@ #include "dynamic_du_factory.h" #include "apps/services/e2_metric_connector_manager.h" +#include "apps/services/worker_manager.h" #include "apps/units/flexible_du/du_high/du_high_commands.h" #include "apps/units/flexible_du/du_high/du_high_config_translators.h" #include "apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h" +#include "apps/units/flexible_du/du_low/du_low_config.h" #include "apps/units/flexible_du/du_low/du_low_config_translator.h" #include "apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h" #include "apps/units/flexible_du/flexible_du_commands.h" -#include "apps/units/flexible_du/split_7_2/ru_ofh_factories.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_factories.h" #include "apps/units/flexible_du/split_8/ru_sdr_factories.h" #include "dynamic_du_impl.h" #include "dynamic_du_translators.h" +#include "dynamic_du_unit_config.h" #include "srsran/du/du_wrapper.h" #include "srsran/du/du_wrapper_factory.h" #include "srsran/pcap/rlc_pcap.h" @@ -105,8 +108,8 @@ create_radio_unit(const std::variant& flexible_du_cfg, std::vector local_du_cfg, @@ -136,7 +139,7 @@ static void update_du_metrics(std::vector& flexibl } } -du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_dependencies& dependencies) +du_unit srsran::create_dynamic_du(const dynamic_du_unit_config& dyn_du_cfg, const du_unit_dependencies& dependencies) { du_unit du_cmd_wrapper; @@ -277,9 +280,6 @@ du_unit srsran::create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_depe // As the temporal configuration contains only one cell, pick the data from that cell. du_cfg.du_high_cfg.fapi.l2_nof_slots_ahead = fapi_cfg.l2_nof_slots_ahead; du_cfg.du_high_cfg.fapi.executor.emplace(dependencies.workers->fapi_exec[i]); - } else { - report_error_if_not(dependencies.workers->fapi_exec[i] == nullptr, - "FAPI buffered worker created for a cell with no MAC delay configured"); } du_insts.push_back(make_du_wrapper(du_cfg)); diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h index 8741931064..757d001b59 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.h @@ -10,7 +10,6 @@ #pragma once -#include "apps/services/worker_manager.h" #include "apps/units/flexible_du/du_unit.h" namespace srsran { @@ -19,6 +18,12 @@ namespace app_services { class metrics_notifier; } +namespace srs_du { +class f1c_connection_client; +class f1u_du_gateway; +} // namespace srs_du + +struct dynamic_du_unit_config; class e2_connection_client; class e2_metric_connector_manager; class f1ap_message_notifier; @@ -31,11 +36,6 @@ class timer_manager; class upper_phy_rg_gateway; class upper_phy_rx_symbol_request_notifier; -namespace srs_du { -class f1c_connection_client; -class f1u_du_gateway; -} // namespace srs_du - -du_unit create_du(const dynamic_du_unit_config& dyn_du_cfg, du_unit_dependencies& dependencies); +du_unit create_dynamic_du(const dynamic_du_unit_config& dyn_du_cfg, const du_unit_dependencies& dependencies); } // namespace srsran diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp index 99ce0bcb5c..99304f820b 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp @@ -9,6 +9,12 @@ */ #include "dynamic_du_translators.h" +#include "apps/services/worker_manager_config.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/du_low/du_low_config_translator.h" +#include "apps/units/flexible_du/fapi/fapi_config_translator.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.h" +#include "apps/units/flexible_du/split_8/ru_sdr_config_translator.h" #include "dynamic_du_unit_config.h" #include "srsran/du/du_cell_config.h" @@ -39,3 +45,40 @@ ru_dummy_configuration srsran::generate_ru_dummy_config(const ru_dummy_unit_conf return out_cfg; } + +static void fill_dummy_worker_manager_config(worker_manager_config& config, const ru_dummy_unit_config& ru_cfg) +{ + config.ru_dummy_cfg.emplace(); + + srsran_assert(config.config_affinities.size() == ru_cfg.cell_affinities.size(), "Invalid number of cell affinities"); + + for (unsigned i = 0, e = ru_cfg.cell_affinities.size(); i != e; ++i) { + config.config_affinities[i].push_back(ru_cfg.cell_affinities[i].ru_cpu_cfg); + } +} + +void srsran::fill_dynamic_du_worker_manager_config(worker_manager_config& config, + const dynamic_du_unit_config& unit_cfg) +{ + bool is_blocking_mode_enable = false; + if (std::holds_alternative(unit_cfg.ru_cfg)) { + is_blocking_mode_enable = std::get(unit_cfg.ru_cfg).device_driver == "zmq"; + } + unsigned nof_cells = unit_cfg.du_high_cfg.config.cells_cfg.size(); + fill_du_high_worker_manager_config(config, unit_cfg.du_high_cfg.config, is_blocking_mode_enable); + fill_du_low_worker_manager_config(config, unit_cfg.du_low_cfg, is_blocking_mode_enable, nof_cells); + fill_fapi_worker_manager_config(config, unit_cfg.fapi_cfg, nof_cells); + + if (std::holds_alternative(unit_cfg.ru_cfg)) { + fill_sdr_worker_manager_config(config, std::get(unit_cfg.ru_cfg)); + } + + if (std::holds_alternative(unit_cfg.ru_cfg)) { + auto cells = generate_du_cell_config(unit_cfg.du_high_cfg.config); + fill_ofh_worker_manager_config(config, std::get(unit_cfg.ru_cfg).config, cells); + } + + if (std::holds_alternative(unit_cfg.ru_cfg)) { + fill_dummy_worker_manager_config(config, std::get(unit_cfg.ru_cfg)); + } +} diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h index 9f2b97b07f..52b9354100 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.h @@ -19,7 +19,9 @@ namespace srs_du { struct du_cell_config; } +struct dynamic_du_unit_config; struct ru_dummy_unit_config; +struct worker_manager_config; /// Generates the dummy RU configuration from the given application unit configuration. ru_dummy_configuration generate_ru_dummy_config(const ru_dummy_unit_config& ru_cfg, @@ -27,4 +29,7 @@ ru_dummy_configuration generate_ru_dummy_config(const ru_dummy_unit_config& unsigned max_processing_delay_slots, unsigned nof_prach_ports); +/// Fills the dynamic_du worker manager parameters of the given worker manager configuration. +void fill_dynamic_du_worker_manager_config(worker_manager_config& config, const dynamic_du_unit_config& unit_cfg); + } // namespace srsran diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp index 203930abb5..3bc09a73f0 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp @@ -12,7 +12,7 @@ #include "apps/units/flexible_du/du_high/du_high_config_cli11_schema.h" #include "apps/units/flexible_du/du_low/du_low_config_cli11_schema.h" #include "apps/units/flexible_du/fapi/fapi_config_cli11_schema.h" -#include "apps/units/flexible_du/split_7_2/ru_ofh_config_cli11_schema.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_cli11_schema.h" #include "apps/units/flexible_du/split_8/ru_sdr_config_cli11_schema.h" #include "apps/units/flexible_du/support/cli11_cpu_affinities_parser_helper.h" #include "dynamic_du_unit_config.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h index 20b41186d1..f5b75df5f7 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h @@ -13,7 +13,7 @@ #include "apps/units/flexible_du/du_high/du_high_config.h" #include "apps/units/flexible_du/du_low/du_low_config.h" #include "apps/units/flexible_du/fapi/fapi_config.h" -#include "apps/units/flexible_du/split_7_2/ru_ofh_config.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config.h" #include "apps/units/flexible_du/split_8/ru_sdr_config.h" #include diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp index fec769c843..9548bf2ca5 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp @@ -11,7 +11,7 @@ #include "dynamic_du_unit_config_validator.h" #include "apps/units/flexible_du/du_high/du_high_config_validator.h" #include "apps/units/flexible_du/du_low/du_low_config_validator.h" -#include "apps/units/flexible_du/split_7_2/ru_ofh_config_validator.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_validator.h" #include "apps/units/flexible_du/split_8/ru_sdr_config_validator.h" #include "srsran/ran/prach/prach_configuration.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp index 937f5c776a..910392ce9b 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp @@ -12,7 +12,7 @@ #include "apps/units/flexible_du/du_high/du_high_config_yaml_writer.h" #include "apps/units/flexible_du/du_low/du_low_config_yaml_writer.h" #include "apps/units/flexible_du/fapi/fapi_config_yaml_writer.h" -#include "apps/units/flexible_du/split_7_2/ru_ofh_config_yaml_writer.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_yaml_writer.h" #include "apps/units/flexible_du/split_8/ru_sdr_config_yaml_writer.h" #include "dynamic_du_unit_config.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h index 18fcf1a2b9..159bbb15cf 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h @@ -13,7 +13,7 @@ #include "apps/units/flexible_du/du_high/du_high_logger_registrator.h" #include "apps/units/flexible_du/du_low/du_low_logger_registrator.h" #include "apps/units/flexible_du/fapi/fapi_logger_registrator.h" -#include "apps/units/flexible_du/split_7_2/ru_ofh_logger_registrator.h" +#include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_logger_registrator.h" #include "apps/units/flexible_du/split_8/ru_sdr_logger_registrator.h" #include "dynamic_du_unit_config.h" From 40fedfc387ed86073219edfb2dbe4b6e45a5a794 Mon Sep 17 00:00:00 2001 From: qarlosalberto Date: Tue, 24 Sep 2024 10:21:01 +0200 Subject: [PATCH 122/174] ci: move stop gnb --- tests/e2e/tests/steps/stub.py | 5 ++++- tests/e2e/tests/viavi.py | 11 ++++++----- tests/e2e/tests/viavi/test_declaration.yml | 2 +- tests/e2e/tests/viavi/test_declaration_debug.yml | 3 ++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/e2e/tests/steps/stub.py b/tests/e2e/tests/steps/stub.py index 94439a9eb9..720f817f06 100644 --- a/tests/e2e/tests/steps/stub.py +++ b/tests/e2e/tests/steps/stub.py @@ -680,6 +680,7 @@ def _stop_stub( """ error_msg = "" + warning_count = 0 with suppress(grpc.RpcError): stop_info: StopResponse = stub.Stop(UInt32Value(value=timeout)) @@ -706,7 +707,9 @@ def _stop_stub( else: logging.info("%s has stopped", name) - return error_msg, stop_info.warning_count + warning_count = stop_info.warning_count + + return error_msg, warning_count def _get_metrics_msg(stub: RanStub, name: str, fail_if_kos: bool = False) -> str: diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index 56e34a6513..b9542da9f0 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -368,8 +368,9 @@ def _test_viavi( # Create campaign logging.info( - f"Starting Campaign {test_declaration.campaign_filename}" - + (f" - Test {test_declaration.test_name}" if test_declaration.test_name is not None else "") + "Starting Campaign %s%s", + test_declaration.campaign_filename, + (f" - Test {test_declaration.test_name}" if test_declaration.test_name is not None else ""), ) campaign_name = viavi.schedule_campaign(test_declaration.campaign_filename, test_declaration.test_name) @@ -383,9 +384,6 @@ def _test_viavi( if info.status is not CampaignStatusEnum.PASS: pytest.fail(f"Viavi Test Failed: {info.message}") # Final stop - _, gnb_warning_count = _stop_stub( - gnb, "GNB", retina_data, gnb_stop_timeout, log_search, test_declaration.warning_as_errors - ) stop( (), gnb, @@ -410,6 +408,9 @@ def _test_viavi( logging.info("Folder with Viavi report: %s", report_folder) logging.info("Downloading Viavi report") viavi.download_directory(report_folder, Path(test_log_folder).joinpath("viavi")) + _, gnb_warning_count = _stop_stub( + gnb, "GNB", retina_data, gnb_stop_timeout, log_search, test_declaration.warning_as_errors + ) check_metrics_criteria( test_configuration=test_declaration, gnb=gnb, diff --git a/tests/e2e/tests/viavi/test_declaration.yml b/tests/e2e/tests/viavi/test_declaration.yml index 08dc6ba55f..d488174d7d 100644 --- a/tests/e2e/tests/viavi/test_declaration.yml +++ b/tests/e2e/tests/viavi/test_declaration.yml @@ -21,7 +21,7 @@ campaign_filename: &campaign_filename "C:\\ci\\CI 4x4 ORAN-FH-complete.xml" gnb_extra_commands: &gnb_extra_commands "ru_ofh --ta4_max 700 --ta4_min 10 metrics --rlc_report_period=1000" -test_timeout: &test_timeout 1800 # 30 * 60 +test_timeout: &test_timeout 2400 # 40 * 60 tests: - campaign_filename: *campaign_filename diff --git a/tests/e2e/tests/viavi/test_declaration_debug.yml b/tests/e2e/tests/viavi/test_declaration_debug.yml index 1f03e5b1aa..496cfecde8 100644 --- a/tests/e2e/tests/viavi/test_declaration_debug.yml +++ b/tests/e2e/tests/viavi/test_declaration_debug.yml @@ -21,11 +21,12 @@ campaign_filename: &campaign_filename "C:\\ci\\CI 4x4 ORAN-FH-complete.xml" gnb_extra_commands: &gnb_extra_commands "metrics --rlc_report_period=1000" +test_timeout: &test_timeout 2400 # 40 * 60 tests: - campaign_filename: *campaign_filename test_name: "32UE ideal UDP bidirectional" - test_timeout: 1800 # 30 * 60 + test_timeout: *test_timeout gnb_extra_commands: *gnb_extra_commands id: "32UE ideal UDP bidirectional - Debug" max_pdschs_per_slot: 1 From 1f567e7f0b5bbefe9a075b395ddb2efa0b1baf48 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 23 Sep 2024 17:46:20 +0200 Subject: [PATCH 123/174] du: improve latency histogram json metric report --- .../du_high_scheduler_cell_metrics_consumers.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp b/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp index 9ddda9e8bf..7eeb87b3ff 100644 --- a/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp +++ b/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp @@ -62,10 +62,7 @@ DECLARE_METRIC_SET("ue_container", /// cell-wide metrics. DECLARE_METRIC("error_indication_count", metric_error_indication_count, unsigned, ""); DECLARE_METRIC("average_latency", metric_average_latency, unsigned, ""); -DECLARE_METRIC("latency_bin_start_usec", latency_bin_start_usec, unsigned, ""); -DECLARE_METRIC("latency_bin_count", latency_bin_count, unsigned, ""); -DECLARE_METRIC_SET("latency_bin", latency_bin, latency_bin_start_usec, latency_bin_count); -DECLARE_METRIC_LIST("latency_histogram", latency_histogram, std::vector); +DECLARE_METRIC("latency_histogram", latency_histogram, std::vector, ""); DECLARE_METRIC_SET("cell_metrics", cell_metrics, metric_error_indication_count, @@ -234,14 +231,8 @@ void scheduler_cell_metrics_consumer_json::handle_metric(const app_services::met auto& cell_output = ctx.get(); cell_output.write(metrics.nof_error_indications); cell_output.write(metrics.average_decision_latency.count()); - unsigned bin_idx = 0; - for (unsigned bin_count : metrics.latency_histogram) { - cell_output.get().emplace_back(); - auto& elem = cell_output.get().back(); - elem.write(bin_idx * scheduler_cell_metrics::nof_usec_per_bin); - elem.write(bin_count); - bin_idx++; - } + cell_output.write( + std::vector(metrics.latency_histogram.begin(), metrics.latency_histogram.end())); // Log the context. ctx.write(get_time_stamp()); From 83396e2e5894f7195beb190a7e4247c4de63e969 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 23 Sep 2024 18:17:59 +0200 Subject: [PATCH 124/174] sched: pre-reserve metrics report ue list --- lib/scheduler/logging/scheduler_metric_handler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/scheduler/logging/scheduler_metric_handler.cpp b/lib/scheduler/logging/scheduler_metric_handler.cpp index c9e8047f92..adaefaffc9 100644 --- a/lib/scheduler/logging/scheduler_metric_handler.cpp +++ b/lib/scheduler/logging/scheduler_metric_handler.cpp @@ -16,6 +16,7 @@ using namespace srsran; cell_metrics_handler::cell_metrics_handler(msecs metrics_report_period, scheduler_metrics_notifier& notifier_) : notifier(notifier_), report_period(metrics_report_period) { + next_report.ue_metrics.reserve(MAX_NOF_DU_UES); } void cell_metrics_handler::handle_ue_creation(du_ue_index_t ue_index, From ea47e0aa64097b6d16952125859e084af668c406 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 23 Sep 2024 18:57:35 +0200 Subject: [PATCH 125/174] sched: add ue events list to scheduler metrics --- include/srsran/scheduler/scheduler_metrics.h | 11 ++++++++++ lib/scheduler/config/sched_config_manager.cpp | 3 +++ .../logging/scheduler_metric_handler.cpp | 21 ++++++++++++++++--- .../logging/scheduler_metrics_handler.h | 7 ++++++- .../scheduler_metrics_ue_configurator.h | 3 +++ .../test_utils/config_generators.cpp | 1 + .../test_utils/dummy_test_components.h | 1 + 7 files changed, 43 insertions(+), 4 deletions(-) diff --git a/include/srsran/scheduler/scheduler_metrics.h b/include/srsran/scheduler/scheduler_metrics.h index 5d2832a026..20528503c6 100644 --- a/include/srsran/scheduler/scheduler_metrics.h +++ b/include/srsran/scheduler/scheduler_metrics.h @@ -15,6 +15,7 @@ #include "srsran/ran/phy_time_unit.h" #include "srsran/ran/rnti.h" #include "srsran/ran/sch/sch_mcs.h" +#include "srsran/ran/slot_point.h" #include "srsran/support/stats.h" #include @@ -50,6 +51,15 @@ struct scheduler_ue_metrics { sample_statistics ri_stats; }; +/// \brief Event that occurred in the cell of the scheduler. +struct scheduler_cell_event { + enum class event_type { ue_add, ue_reconf, ue_rem }; + + slot_point slot; + event_type type; + rnti_t rnti = rnti_t::INVALID_RNTI; +}; + /// \brief Snapshot of the metrics for a cell and its UEs. struct scheduler_cell_metrics { /// Latency histogram number of bins. @@ -66,6 +76,7 @@ struct scheduler_cell_metrics { unsigned nof_error_indications = 0; std::chrono::microseconds average_decision_latency{0}; std::array latency_histogram{0}; + std::vector events; std::vector ue_metrics; }; diff --git a/lib/scheduler/config/sched_config_manager.cpp b/lib/scheduler/config/sched_config_manager.cpp index d4c6fb03e7..e75c550613 100644 --- a/lib/scheduler/config/sched_config_manager.cpp +++ b/lib/scheduler/config/sched_config_manager.cpp @@ -195,6 +195,9 @@ void sched_config_manager::handle_ue_config_complete(du_ue_index_t ue_index, std next_cfg->pcell_common_cfg().pci, next_cfg->pcell_common_cfg().nof_dl_prbs, next_cfg->pcell_common_cfg().nof_slots_per_frame); + } else { + // Reconfiguration case. + cell_metrics[next_cfg->pcell_common_cfg().cell_index]->handle_ue_reconfiguration(ue_index, next_cfg->crnti); } // Stores new UE config and deletes old config. diff --git a/lib/scheduler/logging/scheduler_metric_handler.cpp b/lib/scheduler/logging/scheduler_metric_handler.cpp index adaefaffc9..7174b39e3d 100644 --- a/lib/scheduler/logging/scheduler_metric_handler.cpp +++ b/lib/scheduler/logging/scheduler_metric_handler.cpp @@ -17,6 +17,7 @@ cell_metrics_handler::cell_metrics_handler(msecs metrics_report_period, schedule notifier(notifier_), report_period(metrics_report_period) { next_report.ue_metrics.reserve(MAX_NOF_DU_UES); + next_report.events.reserve(MAX_NOF_DU_UES); } void cell_metrics_handler::handle_ue_creation(du_ue_index_t ue_index, @@ -33,12 +34,22 @@ void cell_metrics_handler::handle_ue_creation(du_ue_index_t ue_index, ues[ue_index].num_slots_per_frame = num_slots_per_frame; rnti_to_ue_index_lookup.emplace(rnti, ue_index); nof_prbs = num_prbs; + + next_report.events.push_back(scheduler_cell_event{last_slot_tx, scheduler_cell_event::event_type::ue_add, rnti}); +} + +void cell_metrics_handler::handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) +{ + next_report.events.push_back(scheduler_cell_event{last_slot_tx, scheduler_cell_event::event_type::ue_reconf, rnti}); } void cell_metrics_handler::handle_ue_deletion(du_ue_index_t ue_index) { if (ues.contains(ue_index)) { - rnti_to_ue_index_lookup.erase(ues[ue_index].rnti); + rnti_t rnti = ues[ue_index].rnti; + next_report.events.push_back(scheduler_cell_event{last_slot_tx, scheduler_cell_event::event_type::ue_rem, rnti}); + + rnti_to_ue_index_lookup.erase(rnti); ues.erase(ue_index); } } @@ -188,8 +199,6 @@ void cell_metrics_handler::handle_error_indication() void cell_metrics_handler::report_metrics() { - next_report.ue_metrics.clear(); - for (ue_metric_context& ue : ues) { // Compute statistics of the UE metrics and push the result to the report. scheduler_ue_metrics sched_ue_metrics = ue.compute_report(report_period); @@ -216,6 +225,10 @@ void cell_metrics_handler::report_metrics() // Report all UE metrics in a batch. notifier.report_metrics(next_report); + + // Clear lists in preparation for the next report. + next_report.ue_metrics.clear(); + next_report.events.clear(); } void cell_metrics_handler::handle_slot_result(const sched_result& slot_result, @@ -295,6 +308,8 @@ void cell_metrics_handler::push_result(slot_point sl_tx, report_period_slots = usecs{report_period} / slot_dur; } + last_slot_tx = sl_tx; + handle_slot_result(slot_result, slot_decision_latency); ++slot_counter; diff --git a/lib/scheduler/logging/scheduler_metrics_handler.h b/lib/scheduler/logging/scheduler_metrics_handler.h index 4d91b2e40a..cb1726c291 100644 --- a/lib/scheduler/logging/scheduler_metrics_handler.h +++ b/lib/scheduler/logging/scheduler_metrics_handler.h @@ -75,9 +75,11 @@ class cell_metrics_handler final : public harq_timeout_handler, public sched_met scheduler_metrics_notifier& notifier; const std::chrono::milliseconds report_period; - /// Derived value. + // Derived value. unsigned report_period_slots = 0; + slot_point last_slot_tx; + unsigned error_indication_counter = 0; std::chrono::microseconds decision_latency_sum{0}; std::array decision_latency_hist{}; @@ -111,6 +113,9 @@ class cell_metrics_handler final : public harq_timeout_handler, public sched_met unsigned num_prbs, unsigned num_slots_per_frame) override; + /// \brief Register UE reconfiguration. + void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) override; + /// \brief Register removal of a UE. void handle_ue_deletion(du_ue_index_t ue_index) override; diff --git a/lib/scheduler/logging/scheduler_metrics_ue_configurator.h b/lib/scheduler/logging/scheduler_metrics_ue_configurator.h index 2cad9f7a2b..fa2010a1f6 100644 --- a/lib/scheduler/logging/scheduler_metrics_ue_configurator.h +++ b/lib/scheduler/logging/scheduler_metrics_ue_configurator.h @@ -29,6 +29,9 @@ class sched_metrics_ue_configurator unsigned num_prbs, unsigned num_slots_per_frame) = 0; + /// Handle a reconfiguration of an existing UE. + virtual void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) = 0; + /// Removes a UE from the reported metrics. virtual void handle_ue_deletion(du_ue_index_t ue_index) = 0; }; diff --git a/tests/unittests/scheduler/test_utils/config_generators.cpp b/tests/unittests/scheduler/test_utils/config_generators.cpp index c65c224c0b..6d7e75feb4 100644 --- a/tests/unittests/scheduler/test_utils/config_generators.cpp +++ b/tests/unittests/scheduler/test_utils/config_generators.cpp @@ -39,6 +39,7 @@ class dummy_sched_metrics_ue_configurator : public sched_metrics_ue_configurator unsigned num_slots_per_frame) override { } + void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) override {} void handle_ue_deletion(du_ue_index_t ue_index) override {} }; diff --git a/tests/unittests/scheduler/test_utils/dummy_test_components.h b/tests/unittests/scheduler/test_utils/dummy_test_components.h index 6a3b4b8a2c..56ac363d02 100644 --- a/tests/unittests/scheduler/test_utils/dummy_test_components.h +++ b/tests/unittests/scheduler/test_utils/dummy_test_components.h @@ -192,6 +192,7 @@ class scheduler_ue_metrics_dummy_configurator : public sched_metrics_ue_configur unsigned num_slots_per_frame) override { } + void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) override {} void handle_ue_deletion(du_ue_index_t ue_index) override {} }; From d4cc912ca4a6a89e99f2c945a67b57f099ba4993 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 23 Sep 2024 19:39:19 +0200 Subject: [PATCH 126/174] sched: implement formatting of cell events in the scheduler metrics --- ..._high_scheduler_cell_metrics_consumers.cpp | 48 ++++++++++++++++++- include/srsran/scheduler/scheduler_metrics.h | 2 +- lib/scheduler/config/sched_config_manager.cpp | 2 +- .../logging/scheduler_metric_handler.cpp | 9 ++-- .../logging/scheduler_metrics_handler.h | 2 +- .../scheduler_metrics_ue_configurator.h | 2 +- .../test_utils/config_generators.cpp | 2 +- .../test_utils/dummy_test_components.h | 2 +- 8 files changed, 58 insertions(+), 11 deletions(-) diff --git a/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp b/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp index 7eeb87b3ff..e3a57ffa09 100644 --- a/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp +++ b/apps/units/flexible_du/du_high/metrics/du_high_scheduler_cell_metrics_consumers.cpp @@ -59,6 +59,12 @@ DECLARE_METRIC_SET("ue_container", metric_ul_nof_nok, metric_bsr); +// Cell event metrics. +DECLARE_METRIC("sfn", metric_sfn, uint16_t, ""); +DECLARE_METRIC("slot_index", metric_slot_index, uint16_t, ""); +DECLARE_METRIC("event_type", metric_event_type, std::string, ""); +DECLARE_METRIC_SET("cell_events", mset_cell_event, metric_sfn, metric_slot_index, metric_rnti, metric_event_type); + /// cell-wide metrics. DECLARE_METRIC("error_indication_count", metric_error_indication_count, unsigned, ""); DECLARE_METRIC("average_latency", metric_average_latency, unsigned, ""); @@ -72,9 +78,10 @@ DECLARE_METRIC_SET("cell_metrics", /// Metrics root object. DECLARE_METRIC("timestamp", metric_timestamp_tag, double, ""); DECLARE_METRIC_LIST("ue_list", mlist_ues, std::vector); +DECLARE_METRIC_LIST("event_list", mlist_events, std::vector); /// Metrics context. -using metric_context_t = srslog::build_context_type; +using metric_context_t = srslog::build_context_type; } // namespace @@ -88,6 +95,21 @@ static void print_header() " ta phr\n"); } +static const char* event_to_string(scheduler_cell_event::event_type ev) +{ + switch (ev) { + case scheduler_cell_event::event_type::ue_add: + return "ue_create"; + case scheduler_cell_event::event_type::ue_reconf: + return "ue_reconf"; + case scheduler_cell_event::event_type::ue_rem: + return "ue_rem"; + default: + break; + } + return "invalid"; +} + void scheduler_cell_metrics_consumer_stdout::handle_metric(const app_services::metrics_set& metric) { if (!print_metrics) { @@ -228,6 +250,16 @@ void scheduler_cell_metrics_consumer_json::handle_metric(const app_services::met output.write(ue.bsr); } + for (const auto& event : metrics.events) { + ctx.get().emplace_back(); + auto& output = ctx.get().back(); + + output.write(event.slot.sfn()); + output.write(event.slot.slot_index()); + output.write(to_value(event.rnti)); + output.write(event_to_string(event.type)); + } + auto& cell_output = ctx.get(); cell_output.write(metrics.nof_error_indications); cell_output.write(metrics.average_decision_latency.count()); @@ -252,6 +284,20 @@ void scheduler_cell_metrics_consumer_log::handle_metric(const app_services::metr metrics.nof_error_indications, metrics.average_decision_latency.count(), fmt::join(metrics.latency_histogram.begin(), metrics.latency_histogram.end(), ", ")); + if (not metrics.events.empty()) { + fmt::format_to(buffer, " events=["); + bool first = true; + for (const auto& event : metrics.events) { + fmt::format_to(buffer, + "{}{{rnti={} slot={} type={}}}", + first ? "" : ", ", + event.rnti, + event.slot, + event_to_string(event.type)); + first = false; + } + fmt::format_to(buffer, "]"); + } logger.info("{}", to_c_str(buffer)); buffer.clear(); diff --git a/include/srsran/scheduler/scheduler_metrics.h b/include/srsran/scheduler/scheduler_metrics.h index 20528503c6..4381bf56e2 100644 --- a/include/srsran/scheduler/scheduler_metrics.h +++ b/include/srsran/scheduler/scheduler_metrics.h @@ -56,8 +56,8 @@ struct scheduler_cell_event { enum class event_type { ue_add, ue_reconf, ue_rem }; slot_point slot; - event_type type; rnti_t rnti = rnti_t::INVALID_RNTI; + event_type type; }; /// \brief Snapshot of the metrics for a cell and its UEs. diff --git a/lib/scheduler/config/sched_config_manager.cpp b/lib/scheduler/config/sched_config_manager.cpp index e75c550613..f0b8f67f59 100644 --- a/lib/scheduler/config/sched_config_manager.cpp +++ b/lib/scheduler/config/sched_config_manager.cpp @@ -197,7 +197,7 @@ void sched_config_manager::handle_ue_config_complete(du_ue_index_t ue_index, std next_cfg->pcell_common_cfg().nof_slots_per_frame); } else { // Reconfiguration case. - cell_metrics[next_cfg->pcell_common_cfg().cell_index]->handle_ue_reconfiguration(ue_index, next_cfg->crnti); + cell_metrics[next_cfg->pcell_common_cfg().cell_index]->handle_ue_reconfiguration(ue_index); } // Stores new UE config and deletes old config. diff --git a/lib/scheduler/logging/scheduler_metric_handler.cpp b/lib/scheduler/logging/scheduler_metric_handler.cpp index 7174b39e3d..e08e37d340 100644 --- a/lib/scheduler/logging/scheduler_metric_handler.cpp +++ b/lib/scheduler/logging/scheduler_metric_handler.cpp @@ -35,19 +35,20 @@ void cell_metrics_handler::handle_ue_creation(du_ue_index_t ue_index, rnti_to_ue_index_lookup.emplace(rnti, ue_index); nof_prbs = num_prbs; - next_report.events.push_back(scheduler_cell_event{last_slot_tx, scheduler_cell_event::event_type::ue_add, rnti}); + next_report.events.push_back(scheduler_cell_event{last_slot_tx, rnti, scheduler_cell_event::event_type::ue_add}); } -void cell_metrics_handler::handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) +void cell_metrics_handler::handle_ue_reconfiguration(du_ue_index_t ue_index) { - next_report.events.push_back(scheduler_cell_event{last_slot_tx, scheduler_cell_event::event_type::ue_reconf, rnti}); + next_report.events.push_back( + scheduler_cell_event{last_slot_tx, ues[ue_index].rnti, scheduler_cell_event::event_type::ue_reconf}); } void cell_metrics_handler::handle_ue_deletion(du_ue_index_t ue_index) { if (ues.contains(ue_index)) { rnti_t rnti = ues[ue_index].rnti; - next_report.events.push_back(scheduler_cell_event{last_slot_tx, scheduler_cell_event::event_type::ue_rem, rnti}); + next_report.events.push_back(scheduler_cell_event{last_slot_tx, rnti, scheduler_cell_event::event_type::ue_rem}); rnti_to_ue_index_lookup.erase(rnti); ues.erase(ue_index); diff --git a/lib/scheduler/logging/scheduler_metrics_handler.h b/lib/scheduler/logging/scheduler_metrics_handler.h index cb1726c291..ee53057956 100644 --- a/lib/scheduler/logging/scheduler_metrics_handler.h +++ b/lib/scheduler/logging/scheduler_metrics_handler.h @@ -114,7 +114,7 @@ class cell_metrics_handler final : public harq_timeout_handler, public sched_met unsigned num_slots_per_frame) override; /// \brief Register UE reconfiguration. - void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) override; + void handle_ue_reconfiguration(du_ue_index_t ue_index) override; /// \brief Register removal of a UE. void handle_ue_deletion(du_ue_index_t ue_index) override; diff --git a/lib/scheduler/logging/scheduler_metrics_ue_configurator.h b/lib/scheduler/logging/scheduler_metrics_ue_configurator.h index fa2010a1f6..b5049e0237 100644 --- a/lib/scheduler/logging/scheduler_metrics_ue_configurator.h +++ b/lib/scheduler/logging/scheduler_metrics_ue_configurator.h @@ -30,7 +30,7 @@ class sched_metrics_ue_configurator unsigned num_slots_per_frame) = 0; /// Handle a reconfiguration of an existing UE. - virtual void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) = 0; + virtual void handle_ue_reconfiguration(du_ue_index_t ue_index) = 0; /// Removes a UE from the reported metrics. virtual void handle_ue_deletion(du_ue_index_t ue_index) = 0; diff --git a/tests/unittests/scheduler/test_utils/config_generators.cpp b/tests/unittests/scheduler/test_utils/config_generators.cpp index 6d7e75feb4..dc69ee07fa 100644 --- a/tests/unittests/scheduler/test_utils/config_generators.cpp +++ b/tests/unittests/scheduler/test_utils/config_generators.cpp @@ -39,7 +39,7 @@ class dummy_sched_metrics_ue_configurator : public sched_metrics_ue_configurator unsigned num_slots_per_frame) override { } - void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) override {} + void handle_ue_reconfiguration(du_ue_index_t ue_index) override {} void handle_ue_deletion(du_ue_index_t ue_index) override {} }; diff --git a/tests/unittests/scheduler/test_utils/dummy_test_components.h b/tests/unittests/scheduler/test_utils/dummy_test_components.h index 56ac363d02..2b08be93b1 100644 --- a/tests/unittests/scheduler/test_utils/dummy_test_components.h +++ b/tests/unittests/scheduler/test_utils/dummy_test_components.h @@ -192,7 +192,7 @@ class scheduler_ue_metrics_dummy_configurator : public sched_metrics_ue_configur unsigned num_slots_per_frame) override { } - void handle_ue_reconfiguration(du_ue_index_t ue_index, rnti_t rnti) override {} + void handle_ue_reconfiguration(du_ue_index_t ue_index) override {} void handle_ue_deletion(du_ue_index_t ue_index) override {} }; From f4b2432fbff4ec9a67fdf56107511361b4ec251b Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Mon, 23 Sep 2024 17:10:11 +0200 Subject: [PATCH 127/174] du_high_unit: fix SR period validation based on subcarrier spacing --- .../du_high/du_high_config_validator.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/units/flexible_du/du_high/du_high_config_validator.cpp b/apps/units/flexible_du/du_high/du_high_config_validator.cpp index 66222aee59..8119638e3a 100644 --- a/apps/units/flexible_du/du_high/du_high_config_validator.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_validator.cpp @@ -413,7 +413,13 @@ static bool validate_pucch_cell_unit_config(const du_high_unit_base_cell_config& return false; } - static constexpr std::array valid_sr_period_slots{1, 2, 4, 5, 8, 10, 16, 20, 40, 80, 160, 320}; + // See \c periodicityAndOffset in \c SchedulingRequestResourceConfig of TS 38.331. + static const std::map> mu_to_valid_sr_period_slots_lookup{ + {0, {1, 2, 4, 5, 8, 10, 16, 20, 40, 80}}, + {1, {1, 2, 4, 8, 10, 16, 20, 40, 80, 160}}, + {2, {1, 2, 4, 8, 16, 20, 40, 80, 160, 320}}, + {3, {1, 2, 4, 8, 16, 40, 80, 160, 320, 640}}, + }; const auto sr_period_slots = static_cast(get_nof_slots_per_subframe(scs_common) * pucch_cfg.sr_period_msec); // Check that the SR period in milliseconds leads to an integer number of slots. @@ -424,10 +430,13 @@ static bool validate_pucch_cell_unit_config(const du_high_unit_base_cell_config& get_nof_slots_per_subframe(scs_common)); return false; } - + span valid_sr_period_slots = mu_to_valid_sr_period_slots_lookup.at(to_numerology_value(scs_common)); if (std::find(valid_sr_period_slots.begin(), valid_sr_period_slots.end(), sr_period_slots) == valid_sr_period_slots.end()) { - fmt::print("SR period of {}ms is not valid for {}kHz SCS.\n", pucch_cfg.sr_period_msec, scs_to_khz(scs_common)); + fmt::print("SR period of {}ms (i.e. {} slots) is not valid for {}kHz SCS.\n", + pucch_cfg.sr_period_msec, + sr_period_slots, + scs_to_khz(scs_common)); return false; } From 5417dbcbbef219e2b46a59202255ec5cee50bdc6 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Wed, 18 Sep 2024 11:31:09 +0200 Subject: [PATCH 128/174] flexible_du: add split 7.2 du implementation worker_manager: removed the dependency of the manager with the configurations of the application unit. Added a configuration for the worker manager and translators to fill it from the app unit configs. --- apps/gnb/gnb_appconfig_translators.cpp | 1 + .../units/flexible_du/du_high/du_high_config_translators.cpp | 1 + apps/units/flexible_du/du_low/du_low_config_translator.cpp | 1 + .../flexible_du/du_low/du_low_wrapper_config_helper.cpp | 1 + .../flexible_du/split_6/split6_du_application_unit_impl.cpp | 5 +++++ .../split_7_2/helpers/ru_ofh_config_translator.cpp | 1 + apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp | 1 + 7 files changed, 11 insertions(+) diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index 9b05753590..221554d664 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -12,6 +12,7 @@ #include "apps/services/worker_manager_config.h" #include "apps/units/cu_cp/cu_cp_unit_config.h" #include "gnb_appconfig.h" + #include "srsran/ran/subcarrier_spacing.h" using namespace srsran; diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index e5ff9de10d..1c9d67b7a4 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -11,6 +11,7 @@ #include "du_high_config_translators.h" #include "apps/services/worker_manager_config.h" #include "du_high_config.h" + #include "srsran/du/du_cell_config_helpers.h" #include "srsran/du/du_cell_config_validation.h" #include "srsran/du/du_high/du_qos_config_helpers.h" diff --git a/apps/units/flexible_du/du_low/du_low_config_translator.cpp b/apps/units/flexible_du/du_low/du_low_config_translator.cpp index 5c0cad3527..b3e78eb77b 100644 --- a/apps/units/flexible_du/du_low/du_low_config_translator.cpp +++ b/apps/units/flexible_du/du_low/du_low_config_translator.cpp @@ -11,6 +11,7 @@ #include "du_low_config_translator.h" #include "apps/services/worker_manager_config.h" #include "du_low_config.h" + #include "srsran/du/du_cell_config.h" #include "srsran/phy/upper/upper_phy_factories.h" #include "srsran/ran/duplex_mode.h" diff --git a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp index e751a1af59..4728aac389 100644 --- a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp +++ b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp @@ -9,6 +9,7 @@ */ #include "du_low_wrapper_config_helper.h" + #include "apps/services/worker_manager.h" #include "du_low_config.h" #include "du_low_config_translator.h" diff --git a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp index ca89cfb5a7..be94ca9d1a 100644 --- a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp +++ b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp @@ -17,6 +17,11 @@ #include "split6_du_unit_cli11_schema.h" #include "split6_du_unit_config_validator.h" #include "split6_du_unit_logger_registrator.h" +#include "split6_du_unit_config_validator.h" +#include "apps/units/flexible_du/du_high/du_high_config_yaml_writer.h" +#include "apps/units/flexible_du/fapi/fapi_config_yaml_writer.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/fapi/fapi_config_translator.h" using namespace srsran; diff --git a/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp index bcc21de2e5..d54efa0cbe 100644 --- a/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp +++ b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp @@ -12,6 +12,7 @@ #include "apps/services/worker_manager_config.h" #include "apps/units/flexible_du/du_high/du_high_config.h" #include "ru_ofh_config.h" + #include "srsran/du/du_cell_config.h" using namespace srsran; diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp b/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp index 7e4ed7a2f4..0732f4ceec 100644 --- a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp +++ b/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp @@ -13,6 +13,7 @@ #include "apps/units/flexible_du/du_high/du_high_config.h" #include "apps/units/flexible_du/du_low/du_low_config.h" #include "ru_sdr_config.h" + #include "srsran/du/du_cell_config.h" using namespace srsran; From 6ead233d73b671ec9a1699d7dd60afe734962095 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Mon, 23 Sep 2024 13:12:09 +0200 Subject: [PATCH 129/174] flexible_du: added DU split 8 to the flexible DU --- CMakeLists.txt | 4 +- apps/gnb/gnb_appconfig_translators.cpp | 1 - .../du_high/du_high_config_translators.cpp | 1 - .../du_low/du_low_config_translator.cpp | 1 - .../du_low/du_low_wrapper_config_helper.cpp | 1 - .../split6_du_application_unit_impl.cpp | 5 - .../helpers/ru_ofh_config_translator.cpp | 1 - apps/units/flexible_du/split_8/CMakeLists.txt | 42 ++- .../split_8/helpers/CMakeLists.txt | 18 ++ .../split_8/{ => helpers}/ru_sdr_config.h | 0 .../ru_sdr_config_cli11_schema.cpp | 0 .../ru_sdr_config_cli11_schema.h | 0 .../ru_sdr_config_translator.cpp | 1 - .../{ => helpers}/ru_sdr_config_translator.h | 0 .../{ => helpers}/ru_sdr_config_validator.cpp | 0 .../{ => helpers}/ru_sdr_config_validator.h | 0 .../ru_sdr_config_yaml_writer.cpp | 0 .../{ => helpers}/ru_sdr_config_yaml_writer.h | 0 .../{ => helpers}/ru_sdr_factories.cpp | 0 .../split_8/{ => helpers}/ru_sdr_factories.h | 0 .../{ => helpers}/ru_sdr_logger_registrator.h | 0 .../split_8_du_application_unit_impl.cpp | 68 +++++ .../split_8_du_application_unit_impl.h | 51 ++++ .../split_8/split_8_du_factory.cpp | 263 ++++++++++++++++++ .../flexible_du/split_8/split_8_du_factory.h | 41 +++ .../flexible_du/split_8/split_8_du_impl.cpp | 67 +++++ .../flexible_du/split_8/split_8_du_impl.h | 62 +++++ .../split_8/split_8_du_unit_cli11_schema.cpp | 45 +++ .../split_8/split_8_du_unit_cli11_schema.h | 25 ++ .../split_8/split_8_du_unit_config.h | 32 +++ .../split_8_du_unit_config_validator.cpp | 90 ++++++ .../split_8_du_unit_config_validator.h | 21 ++ .../split_8_du_unit_config_yaml_writer.cpp | 26 ++ .../split_8_du_unit_config_yaml_writer.h | 22 ++ .../split_8_du_unit_logger_registrator.h | 30 ++ .../split_dynamic/dynamic_du_factory.cpp | 2 +- .../split_dynamic/dynamic_du_impl.cpp | 1 - .../split_dynamic/dynamic_du_translators.cpp | 2 +- .../dynamic_du_unit_cli11_schema.cpp | 2 +- .../split_dynamic/dynamic_du_unit_config.h | 2 +- .../dynamic_du_unit_config_validator.cpp | 2 +- .../dynamic_du_unit_config_yaml_writer.cpp | 2 +- .../dynamic_du_unit_logger_registrator.h | 2 +- 43 files changed, 904 insertions(+), 29 deletions(-) create mode 100644 apps/units/flexible_du/split_8/helpers/CMakeLists.txt rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config.h (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_cli11_schema.cpp (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_cli11_schema.h (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_translator.cpp (99%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_translator.h (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_validator.cpp (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_validator.h (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_yaml_writer.cpp (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_config_yaml_writer.h (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_factories.cpp (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_factories.h (100%) rename apps/units/flexible_du/split_8/{ => helpers}/ru_sdr_logger_registrator.h (100%) create mode 100644 apps/units/flexible_du/split_8/split_8_du_application_unit_impl.cpp create mode 100644 apps/units/flexible_du/split_8/split_8_du_application_unit_impl.h create mode 100644 apps/units/flexible_du/split_8/split_8_du_factory.cpp create mode 100644 apps/units/flexible_du/split_8/split_8_du_factory.h create mode 100644 apps/units/flexible_du/split_8/split_8_du_impl.cpp create mode 100644 apps/units/flexible_du/split_8/split_8_du_impl.h create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.cpp create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.h create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_config.h create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_config_validator.cpp create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_config_validator.h create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.cpp create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.h create mode 100644 apps/units/flexible_du/split_8/split_8_du_unit_logger_registrator.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 08dc714aaf..eaecbb590d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -349,7 +349,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${MARCH} -mtune=${MTUNE}") # DU split setup ######################################################################## # Public variable to select the DU split. -set(DU_SPLIT_TYPE "DYNAMIC" CACHE STRING "DU split type. Default value is 'DYNAMIC'. Allowed values: DYNAMIC, SPLIT_6, SPLIT_7_2") +set(DU_SPLIT_TYPE "DYNAMIC" CACHE STRING "DU split type. Default value is 'DYNAMIC'. Allowed values: DYNAMIC, SPLIT_6, SPLIT_7_2, SPLIT_8") # Internal private booleans to represent the selected DU split type. Values auto-derived from DU_SPLIT_TYPE variable. set(DU_SPLIT_DYNAMIC OFF CACHE BOOL "DU dynamic split enabled boolean") @@ -363,6 +363,8 @@ elseif (DU_SPLIT_TYPE STREQUAL "SPLIT_6") set(DU_SPLIT_6 ON) elseif (DU_SPLIT_TYPE STREQUAL "SPLIT_7_2") set(DU_SPLIT_7_2 ON) +elseif (DU_SPLIT_TYPE STREQUAL "SPLIT_8") + set(DU_SPLIT_8 ON) else () message(WARNING "DU split value '${DU_SPLIT_TYPE}' is not supported. Defaulting to 'DYNAMIC'") set(DU_SPLIT_TYPE "DYNAMIC") diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index 221554d664..9b05753590 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -12,7 +12,6 @@ #include "apps/services/worker_manager_config.h" #include "apps/units/cu_cp/cu_cp_unit_config.h" #include "gnb_appconfig.h" - #include "srsran/ran/subcarrier_spacing.h" using namespace srsran; diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index 1c9d67b7a4..e5ff9de10d 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -11,7 +11,6 @@ #include "du_high_config_translators.h" #include "apps/services/worker_manager_config.h" #include "du_high_config.h" - #include "srsran/du/du_cell_config_helpers.h" #include "srsran/du/du_cell_config_validation.h" #include "srsran/du/du_high/du_qos_config_helpers.h" diff --git a/apps/units/flexible_du/du_low/du_low_config_translator.cpp b/apps/units/flexible_du/du_low/du_low_config_translator.cpp index b3e78eb77b..5c0cad3527 100644 --- a/apps/units/flexible_du/du_low/du_low_config_translator.cpp +++ b/apps/units/flexible_du/du_low/du_low_config_translator.cpp @@ -11,7 +11,6 @@ #include "du_low_config_translator.h" #include "apps/services/worker_manager_config.h" #include "du_low_config.h" - #include "srsran/du/du_cell_config.h" #include "srsran/phy/upper/upper_phy_factories.h" #include "srsran/ran/duplex_mode.h" diff --git a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp index 4728aac389..e751a1af59 100644 --- a/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp +++ b/apps/units/flexible_du/du_low/du_low_wrapper_config_helper.cpp @@ -9,7 +9,6 @@ */ #include "du_low_wrapper_config_helper.h" - #include "apps/services/worker_manager.h" #include "du_low_config.h" #include "du_low_config_translator.h" diff --git a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp index be94ca9d1a..ca89cfb5a7 100644 --- a/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp +++ b/apps/units/flexible_du/split_6/split6_du_application_unit_impl.cpp @@ -17,11 +17,6 @@ #include "split6_du_unit_cli11_schema.h" #include "split6_du_unit_config_validator.h" #include "split6_du_unit_logger_registrator.h" -#include "split6_du_unit_config_validator.h" -#include "apps/units/flexible_du/du_high/du_high_config_yaml_writer.h" -#include "apps/units/flexible_du/fapi/fapi_config_yaml_writer.h" -#include "apps/units/flexible_du/du_high/du_high_config_translators.h" -#include "apps/units/flexible_du/fapi/fapi_config_translator.h" using namespace srsran; diff --git a/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp index d54efa0cbe..bcc21de2e5 100644 --- a/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp +++ b/apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.cpp @@ -12,7 +12,6 @@ #include "apps/services/worker_manager_config.h" #include "apps/units/flexible_du/du_high/du_high_config.h" #include "ru_ofh_config.h" - #include "srsran/du/du_cell_config.h" using namespace srsran; diff --git a/apps/units/flexible_du/split_8/CMakeLists.txt b/apps/units/flexible_du/split_8/CMakeLists.txt index 775f97ebdf..83b487f7bc 100644 --- a/apps/units/flexible_du/split_8/CMakeLists.txt +++ b/apps/units/flexible_du/split_8/CMakeLists.txt @@ -6,13 +6,37 @@ # the distribution. # -set(SOURCES - ru_sdr_config_cli11_schema.cpp - ru_sdr_config_translator.cpp - ru_sdr_config_validator.cpp - ru_sdr_config_yaml_writer.cpp - ru_sdr_factories.cpp) -add_library(srsran_split_8_app_unit_helpers STATIC ${SOURCES}) -target_link_libraries(srsran_split_8_app_unit_helpers srsran_ru_generic srsran_lower_phy srsran_flexible_du_helpers) -target_include_directories(srsran_split_8_app_unit_helpers PRIVATE ${CMAKE_SOURCE_DIR}) +add_subdirectory(helpers) + +# Build the flexible du split 8 library when it is selected in the definition. +if (DU_SPLIT_8) + set(SOURCES + split_8_du_application_unit_impl.cpp + split_8_du_factory.cpp + split_8_du_impl.cpp + split_8_du_unit_cli11_schema.cpp + split_8_du_unit_config_validator.cpp + split_8_du_unit_config_yaml_writer.cpp) + + add_library(srsran_flexible_du STATIC ${SOURCES}) + target_include_directories(srsran_flexible_du PRIVATE ${CMAKE_SOURCE_DIR}) + set(FLEXIBLE_DU_LIBRARIES + srsran_du_wrapper + srsran_pcap + srsran_app_services + srsran_fapi_app_unit + srsran_du_low_unit_helpers + srsran_split_8_app_unit_helpers + srsran_du_high_unit_helpers) + + # Hardware acceleration for both PUSCH and PDSCH is enabled by default when using DPDK. + if (DPDK_FOUND) + set_source_files_properties(split_8_du_factory.cpp PROPERTIES COMPILE_DEFINITIONS "DPDK_FOUND; HWACC_PDSCH_ENABLED; HWACC_PUSCH_ENABLED") + list(APPEND FLEXIBLE_DU_LIBRARIES hal_hwacc_pusch + hal_hwacc_pdsch + hal_bbdev_factory) + endif (DPDK_FOUND) + target_link_libraries(srsran_flexible_du ${FLEXIBLE_DU_LIBRARIES}) + +endif () diff --git a/apps/units/flexible_du/split_8/helpers/CMakeLists.txt b/apps/units/flexible_du/split_8/helpers/CMakeLists.txt new file mode 100644 index 0000000000..275f4fd595 --- /dev/null +++ b/apps/units/flexible_du/split_8/helpers/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# Copyright 2021-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +set(SOURCES + ru_sdr_config_cli11_schema.cpp + ru_sdr_config_translator.cpp + ru_sdr_config_validator.cpp + ru_sdr_config_yaml_writer.cpp + ru_sdr_factories.cpp) + +add_library(srsran_split_8_app_unit_helpers STATIC ${SOURCES}) +target_link_libraries(srsran_split_8_app_unit_helpers srsran_ru_generic srsran_lower_phy srsran_flexible_du_helpers) +target_include_directories(srsran_split_8_app_unit_helpers PRIVATE ${CMAKE_SOURCE_DIR}) diff --git a/apps/units/flexible_du/split_8/ru_sdr_config.h b/apps/units/flexible_du/split_8/helpers/ru_sdr_config.h similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config.h rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config.h diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_cli11_schema.cpp b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_cli11_schema.cpp similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config_cli11_schema.cpp rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_cli11_schema.cpp diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_cli11_schema.h b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_cli11_schema.h similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config_cli11_schema.h rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_cli11_schema.h diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_translator.cpp similarity index 99% rename from apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_translator.cpp index 0732f4ceec..7e4ed7a2f4 100644 --- a/apps/units/flexible_du/split_8/ru_sdr_config_translator.cpp +++ b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_translator.cpp @@ -13,7 +13,6 @@ #include "apps/units/flexible_du/du_high/du_high_config.h" #include "apps/units/flexible_du/du_low/du_low_config.h" #include "ru_sdr_config.h" - #include "srsran/du/du_cell_config.h" using namespace srsran; diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_translator.h b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_translator.h similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config_translator.h rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_translator.h diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_validator.cpp b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_validator.cpp similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config_validator.cpp rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_validator.cpp diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_validator.h b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_validator.h similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config_validator.h rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_validator.h diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_yaml_writer.cpp b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_yaml_writer.cpp similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config_yaml_writer.cpp rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_yaml_writer.cpp diff --git a/apps/units/flexible_du/split_8/ru_sdr_config_yaml_writer.h b/apps/units/flexible_du/split_8/helpers/ru_sdr_config_yaml_writer.h similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_config_yaml_writer.h rename to apps/units/flexible_du/split_8/helpers/ru_sdr_config_yaml_writer.h diff --git a/apps/units/flexible_du/split_8/ru_sdr_factories.cpp b/apps/units/flexible_du/split_8/helpers/ru_sdr_factories.cpp similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_factories.cpp rename to apps/units/flexible_du/split_8/helpers/ru_sdr_factories.cpp diff --git a/apps/units/flexible_du/split_8/ru_sdr_factories.h b/apps/units/flexible_du/split_8/helpers/ru_sdr_factories.h similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_factories.h rename to apps/units/flexible_du/split_8/helpers/ru_sdr_factories.h diff --git a/apps/units/flexible_du/split_8/ru_sdr_logger_registrator.h b/apps/units/flexible_du/split_8/helpers/ru_sdr_logger_registrator.h similarity index 100% rename from apps/units/flexible_du/split_8/ru_sdr_logger_registrator.h rename to apps/units/flexible_du/split_8/helpers/ru_sdr_logger_registrator.h diff --git a/apps/units/flexible_du/split_8/split_8_du_application_unit_impl.cpp b/apps/units/flexible_du/split_8/split_8_du_application_unit_impl.cpp new file mode 100644 index 0000000000..1773f85a58 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_application_unit_impl.cpp @@ -0,0 +1,68 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_8_du_application_unit_impl.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/du_low/du_low_config_translator.h" +#include "apps/units/flexible_du/fapi/fapi_config_translator.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_translator.h" +#include "split_8_du_factory.h" +#include "split_8_du_unit_cli11_schema.h" +#include "split_8_du_unit_config_validator.h" +#include "split_8_du_unit_config_yaml_writer.h" +#include "split_8_du_unit_logger_registrator.h" + +using namespace srsran; + +void split_8_du_application_unit_impl::on_loggers_registration() +{ + register_split_8_du_loggers(unit_cfg); +} + +void split_8_du_application_unit_impl::on_configuration_parameters_autoderivation(CLI::App& app) +{ + autoderive_split_8_du_parameters_after_parsing(app, unit_cfg); +} + +bool split_8_du_application_unit_impl::on_configuration_validation( + const os_sched_affinity_bitmask& available_cpus) const +{ + return validate_split_8_du_unit_config(unit_cfg, available_cpus); +} + +void split_8_du_application_unit_impl::on_parsing_configuration_registration(CLI::App& app) +{ + configure_cli11_with_split_8_du_unit_config_schema(app, unit_cfg); +} + +du_unit split_8_du_application_unit_impl::create_flexible_du_unit(const du_unit_dependencies& dependencies) +{ + return create_split_8_du(unit_cfg, dependencies); +} + +std::unique_ptr srsran::create_flexible_du_application_unit() +{ + return std::make_unique(); +} + +void split_8_du_application_unit_impl::dump_config(YAML::Node& node) const +{ + fill_split_8_du_unit_config_in_yaml_schema(node, unit_cfg); +} + +void split_8_du_application_unit_impl::fill_worker_manager_config(worker_manager_config& config) +{ + bool is_blocking_mode_enable = unit_cfg.ru_cfg.device_driver == "zmq"; + unsigned nof_cells = unit_cfg.du_high_cfg.config.cells_cfg.size(); + fill_du_high_worker_manager_config(config, unit_cfg.du_high_cfg.config, is_blocking_mode_enable); + fill_du_low_worker_manager_config(config, unit_cfg.du_low_cfg, is_blocking_mode_enable, nof_cells); + fill_fapi_worker_manager_config(config, unit_cfg.fapi_cfg, nof_cells); + fill_sdr_worker_manager_config(config, unit_cfg.ru_cfg); +} diff --git a/apps/units/flexible_du/split_8/split_8_du_application_unit_impl.h b/apps/units/flexible_du/split_8/split_8_du_application_unit_impl.h new file mode 100644 index 0000000000..8830a6f87a --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_application_unit_impl.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/flexible_du_application_unit.h" +#include "split_8_du_unit_config.h" + +namespace srsran { + +/// Split 8 DU application unit implementation. +class split_8_du_application_unit_impl : public flexible_du_application_unit +{ +public: + // See interface for documentation. + void on_parsing_configuration_registration(CLI::App& app) override; + + // See interface for documentation. + void on_configuration_parameters_autoderivation(CLI::App& app) override; + + // See interface for documentation. + bool on_configuration_validation(const os_sched_affinity_bitmask& available_cpus) const override; + + // See interface for documentation. + void on_loggers_registration() override; + + // See interface for documentation. + du_unit create_flexible_du_unit(const du_unit_dependencies& dependencies) override; + + // See interface for documentation. + du_high_unit_config& get_du_high_unit_config() override { return unit_cfg.du_high_cfg.config; } + const du_high_unit_config& get_du_high_unit_config() const override { return unit_cfg.du_high_cfg.config; } + + // See interface for documentation. + void dump_config(YAML::Node& node) const override; + + // See interface for documentation. + void fill_worker_manager_config(worker_manager_config& config) override; + +private: + split_8_du_unit_config unit_cfg; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/split_8_du_factory.cpp b/apps/units/flexible_du/split_8/split_8_du_factory.cpp new file mode 100644 index 0000000000..11202de1a5 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_factory.cpp @@ -0,0 +1,263 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_8_du_factory.h" +#include "apps/services/e2_metric_connector_manager.h" +#include "apps/services/worker_manager.h" +#include "apps/units/flexible_du/du_high/du_high_commands.h" +#include "apps/units/flexible_du/du_high/du_high_config_translators.h" +#include "apps/units/flexible_du/du_high/du_high_wrapper_config_helper.h" +#include "apps/units/flexible_du/du_low/du_low_config_translator.h" +#include "apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h" +#include "apps/units/flexible_du/flexible_du_commands.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_factories.h" +#include "split_8_du_impl.h" +#include "srsran/du/du_wrapper.h" +#include "srsran/du/du_wrapper_factory.h" +#include "srsran/pcap/rlc_pcap.h" +#include "srsran/ru/ru_dummy_factory.h" +#ifdef DPDK_FOUND +#include "srsran/hal/dpdk/bbdev/bbdev_acc.h" +#include "srsran/hal/dpdk/bbdev/bbdev_acc_factory.h" +#include "srsran/hal/phy/upper/channel_processors/hw_accelerator_factories.h" +#include "srsran/hal/phy/upper/channel_processors/pusch/ext_harq_buffer_context_repository_factory.h" +#include "srsran/hal/phy/upper/channel_processors/pusch/hw_accelerator_factories.h" +#endif // DPDK_FOUND + +using namespace srsran; + +static std::unique_ptr create_radio_unit(const ru_sdr_unit_config& ru_cfg, + worker_manager& workers, + span du_cells, + ru_uplink_plane_rx_symbol_notifier& symbol_notifier, + ru_timing_notifier& timing_notifier, + ru_error_notifier& error_notifier, + unsigned max_processing_delay) +{ + ru_sdr_factory_config config; + config.du_cells = du_cells; + config.ru_cfg = ru_cfg; + config.max_processing_delay_slots = max_processing_delay; + + ru_sdr_factory_dependencies dependencies; + dependencies.workers = &workers; + dependencies.error_notifier = &error_notifier; + dependencies.symbol_notifier = &symbol_notifier; + dependencies.timing_notifier = &timing_notifier; + + return create_sdr_radio_unit(config, dependencies); +} + +/// \brief Update the Flexible DU metrics configuration with the given local DU configuration and E2 configuration. +/// +/// This function manages the multi cell workaround for the DU high metrics. To have multi cell, now one DU is +/// instantiated per cell, so this would create multiple consumers that does not make sense, for example stdout. +/// With this we avoid having 2 different objects that write in the stdout. +static void update_du_metrics(std::vector& flexible_du_cfg, + std::vector local_du_cfg, + bool is_e2_enabled) +{ + // First call, copy everything. + if (flexible_du_cfg.empty()) { + flexible_du_cfg = std::move(local_du_cfg); + return; + } + + // Safe check that all the DUs provides the same amount of metrics. + srsran_assert(flexible_du_cfg.size() == local_du_cfg.size(), + "Flexible DU metrics size '{}' does not match DU metrics size '{}'", + flexible_du_cfg.size(), + local_du_cfg.size()); + + // Iterate the metrics configs of each DU. Each DU should ha + for (unsigned i = 0, e = local_du_cfg.size(); i != e; ++i) { + // Store the metrics producers for each DU. + flexible_du_cfg[i].producers.push_back(std::move(local_du_cfg[i].producers.back())); + + // Move E2 consumers for each DU to the common output config. E2 Consumers occupy the last position. + if (is_e2_enabled) { + flexible_du_cfg[i].consumers.push_back(std::move(local_du_cfg[i].consumers.back())); + } + } +} + +du_unit srsran::create_split_8_du(const split_8_du_unit_config& du_8_cfg, const du_unit_dependencies& dependencies) +{ + du_unit du_cmd_wrapper; + + const du_high_unit_config& du_hi = du_8_cfg.du_high_cfg.config; + const du_low_unit_config& du_lo = du_8_cfg.du_low_cfg; + const fapi_unit_config& fapi_cfg = du_8_cfg.fapi_cfg; + + auto du_cells = generate_du_cell_config(du_hi); + + std::vector> du_insts; + auto du_impl = std::make_unique(du_cells.size()); + + std::vector prach_ports; + std::vector max_pusch_per_slot; + for (const auto& high : du_hi.cells_cfg) { + prach_ports.push_back(high.cell.prach_cfg.ports); + max_pusch_per_slot.push_back(high.cell.pusch_cfg.max_puschs_per_slot); + } + + // Initialize hardware-accelerator (only if needed). + hal_upper_phy_config hal_config = {}; + hal_config.hwacc_pdsch_processor = false; + hal_config.hwacc_pusch_processor = false; +#ifdef DPDK_FOUND + hal::bbdev_hwacc_pdsch_enc_factory_configuration hwacc_pdsch_enc_cfg = {}; + hal::bbdev_hwacc_pusch_dec_factory_configuration hwacc_pusch_dec_cfg = {}; + std::shared_ptr harq_buffer_context = nullptr; + unsigned nof_hwacc_dus = du_cells.size(); + if (!du_lo.hal_config->bbdev_hwacc->hwacc_type.empty()) { + srslog::basic_logger& hwacc_logger = srslog::fetch_basic_logger("HWACC", false); + hwacc_logger.set_level(du_lo.loggers.hal_level); + + // Create a bbdev accelerator factory. + std::unique_ptr bbdev_acc_factory = + srsran::dpdk::create_bbdev_acc_factory(du_lo.hal_config->bbdev_hwacc->bbdev_acc_type); + report_error_if_not(bbdev_acc_factory, + "Unable to create the {} bbdev hardware-accelerator interface factory.", + du_lo.hal_config->bbdev_hwacc->bbdev_acc_type); + + // Intefacing to the bbdev-based hardware-accelerator. + dpdk::bbdev_acc_configuration bbdev_config; + bbdev_config.id = du_lo.hal_config->bbdev_hwacc->id; + if (du_lo.hal_config->bbdev_hwacc->pdsch_enc->nof_hwacc > 0) { + bbdev_config.nof_ldpc_enc_lcores = nof_hwacc_dus * du_lo.hal_config->bbdev_hwacc->pdsch_enc->nof_hwacc; + } + if (du_lo.hal_config->bbdev_hwacc->pusch_dec->nof_hwacc > 0) { + bbdev_config.nof_ldpc_dec_lcores = nof_hwacc_dus * du_lo.hal_config->bbdev_hwacc->pusch_dec->nof_hwacc; + } + // If no msg_mbuf size is defined, a worst-case value will be used. + bbdev_config.msg_mbuf_size = du_lo.hal_config->bbdev_hwacc->msg_mbuf_size.value_or(RTE_BBDEV_LDPC_E_MAX_MBUF); + // If no rm_mbuf size is defined, a worst-case value will be used. + bbdev_config.rm_mbuf_size = du_lo.hal_config->bbdev_hwacc->rm_mbuf_size.value_or(RTE_BBDEV_LDPC_E_MAX_MBUF); + // If no number of mbufs is defined, a worst-case value will be used. + bbdev_config.nof_mbuf = + du_lo.hal_config->bbdev_hwacc->nof_mbuf.value_or(static_cast(pow2(log2_ceil(MAX_NOF_SEGMENTS)))); + std::shared_ptr bbdev_accelerator = bbdev_acc_factory->create(bbdev_config, hwacc_logger); + report_error_if_not( + bbdev_accelerator, "Unable to open the {} hardware-accelerator.", du_lo.hal_config->bbdev_hwacc->hwacc_type); + + // Configure the hardware-accelerated PDSCH encoding factory (only if needed). + if (du_lo.hal_config->bbdev_hwacc->pdsch_enc->nof_hwacc > 0) { + hwacc_pdsch_enc_cfg.acc_type = du_lo.hal_config->bbdev_hwacc->hwacc_type; + hwacc_pdsch_enc_cfg.bbdev_accelerator = bbdev_accelerator; + hwacc_pdsch_enc_cfg.cb_mode = du_lo.hal_config->bbdev_hwacc->pdsch_enc->cb_mode; + // If no maximum buffer size is defined, a worst-case value will be used. + hwacc_pdsch_enc_cfg.max_tb_size = + du_lo.hal_config->bbdev_hwacc->pdsch_enc->max_buffer_size.value_or(RTE_BBDEV_LDPC_E_MAX_MBUF); + hwacc_pdsch_enc_cfg.dedicated_queue = du_lo.hal_config->bbdev_hwacc->pdsch_enc->dedicated_queue; + hal_config.hwacc_pdsch_processor = true; + hal_config.hwacc_pdsch_enc_cfg = hwacc_pdsch_enc_cfg; + } + + // Configure the hardware-accelerated PUSCH decoding factory (only if needed). + if (du_lo.hal_config->bbdev_hwacc->pusch_dec->nof_hwacc > 0) { + hwacc_pusch_dec_cfg.acc_type = du_lo.hal_config->bbdev_hwacc->hwacc_type; + hwacc_pusch_dec_cfg.bbdev_accelerator = bbdev_accelerator; + hwacc_pusch_dec_cfg.ext_softbuffer = du_lo.hal_config->bbdev_hwacc->pusch_dec->ext_softbuffer; + if (hwacc_pusch_dec_cfg.ext_softbuffer) { + // Set up an external HARQ buffer context repository. + unsigned nof_cbs = du_lo.hal_config->bbdev_hwacc->pusch_dec->harq_context_size.value_or(MAX_NOF_SEGMENTS); + uint64_t ext_harq_buff_size = bbdev_accelerator->get_harq_buff_size_bytes(); + harq_buffer_context = hal::create_ext_harq_buffer_context_repository(nof_cbs, ext_harq_buff_size, false); + report_error_if_not(harq_buffer_context, + "Unable to create the external HARQ buffer context for the {} hardware-accelerator.", + du_lo.hal_config->bbdev_hwacc->hwacc_type); + hwacc_pusch_dec_cfg.harq_buffer_context = harq_buffer_context; + } + hwacc_pusch_dec_cfg.dedicated_queue = du_lo.hal_config->bbdev_hwacc->pusch_dec->dedicated_queue; + hal_config.hwacc_pusch_processor = true; + hal_config.hwacc_pusch_dec_cfg = hwacc_pusch_dec_cfg; + } + } +#endif // DPDK_FOUND + + for (unsigned i = 0, e = du_cells.size(); i != e; ++i) { + // Create one DU per cell. + srs_du::du_wrapper_config du_cfg = {}; + du_high_unit_config tmp_cfg = du_hi; + tmp_cfg.cells_cfg.resize(1); + tmp_cfg.cells_cfg[0] = du_hi.cells_cfg[i]; + + make_du_low_wrapper_config_and_dependencies(du_cfg.du_low_cfg, + du_lo, + hal_config, + {prach_ports[i]}, + span(&du_cells[i], 1), + span(&max_pusch_per_slot[i], 1), + du_impl->get_upper_ru_dl_rg_adapter(), + du_impl->get_upper_ru_ul_request_adapter(), + *dependencies.workers, + i); + + auto cell_services_cfg = fill_du_high_wrapper_config(du_cfg.du_high_cfg, + tmp_cfg, + i, + dependencies.workers->get_du_high_executor_mapper(i), + *dependencies.f1c_client_handler, + *dependencies.f1u_gw, + *dependencies.timer_mng, + *dependencies.mac_p, + *dependencies.rlc_p, + *dependencies.e2_client_handler, + *dependencies.e2_metric_connectors, + *dependencies.json_sink, + *dependencies.metrics_notifier); + + update_du_metrics(du_cmd_wrapper.metrics, std::move(cell_services_cfg.first), tmp_cfg.e2_cfg.enable_du_e2); + + // Use the commands of the first cell. + if (i == 0) { + for (auto& command : cell_services_cfg.second) + du_cmd_wrapper.commands.push_back(std::move(command)); + } + + // FAPI configuration. + du_cfg.du_high_cfg.fapi.log_level = fapi_cfg.fapi_level; + if (fapi_cfg.l2_nof_slots_ahead != 0) { + // As the temporal configuration contains only one cell, pick the data from that cell. + du_cfg.du_high_cfg.fapi.l2_nof_slots_ahead = fapi_cfg.l2_nof_slots_ahead; + du_cfg.du_high_cfg.fapi.executor.emplace(dependencies.workers->fapi_exec[i]); + } + + du_insts.push_back(make_du_wrapper(du_cfg)); + report_error_if_not(du_insts.back(), "Invalid Distributed Unit"); + } + + std::unique_ptr ru = create_radio_unit(du_8_cfg.ru_cfg, + *dependencies.workers, + du_cells, + du_impl->get_upper_ru_ul_adapter(), + du_impl->get_upper_ru_timing_adapter(), + du_impl->get_upper_ru_error_adapter(), + du_lo.expert_phy_cfg.max_processing_delay_slots); + + srsran_assert(ru, "Invalid Radio Unit"); + + // Add RU commands. + du_cmd_wrapper.commands.push_back(std::make_unique()); + du_cmd_wrapper.commands.push_back(std::make_unique(ru->get_controller())); + du_cmd_wrapper.commands.push_back(std::make_unique(ru->get_controller())); + du_cmd_wrapper.commands.push_back(std::make_unique(ru->get_controller())); + + du_impl->add_ru(std::move(ru)); + du_impl->add_dus(std::move(du_insts)); + + du_cmd_wrapper.unit = std::move(du_impl); + + // Configure the application unit metrics for the DU high. + announce_du_high_cells(du_hi); + + return du_cmd_wrapper; +} diff --git a/apps/units/flexible_du/split_8/split_8_du_factory.h b/apps/units/flexible_du/split_8/split_8_du_factory.h new file mode 100644 index 0000000000..186d9b1d13 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_factory.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_unit.h" +#include "split_8_du_unit_config.h" + +namespace srsran { + +namespace app_services { +class metrics_notifier; +} + +class e2_connection_client; +class e2_metric_connector_manager; +class f1ap_message_notifier; +class console_helper; +class metrics_log_helper; +class metrics_plotter_json; +class metrics_plotter_stdout; +class mac_pcap; +class timer_manager; +class upper_phy_rg_gateway; +class upper_phy_rx_symbol_request_notifier; + +namespace srs_du { +class f1c_connection_client; +class f1u_du_gateway; +} // namespace srs_du + +du_unit create_split_8_du(const split_8_du_unit_config& du_8_cfg, const du_unit_dependencies& dependencies); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/split_8_du_impl.cpp b/apps/units/flexible_du/split_8/split_8_du_impl.cpp new file mode 100644 index 0000000000..4bfb4376d7 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_impl.cpp @@ -0,0 +1,67 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_8_du_impl.h" +#include "srsran/du/du_low/du_low.h" +#include "srsran/du/du_low/du_low_wrapper.h" +#include "srsran/du/du_wrapper.h" +#include "srsran/phy/upper/upper_phy.h" +#include "srsran/ru/ru.h" +#include "srsran/ru/ru_controller.h" + +using namespace srsran; + +split_8_du_impl::split_8_du_impl(unsigned nof_cells) : + ru_ul_adapt(nof_cells), ru_timing_adapt(nof_cells), ru_error_adapt(nof_cells) +{ +} + +void split_8_du_impl::start() +{ + for (auto& du_obj : du_list) { + du_obj->get_power_controller().start(); + } + + ru->get_controller().start(); +} + +void split_8_du_impl::stop() +{ + ru->get_controller().stop(); + + for (auto& du_obj : du_list) { + du_obj->get_power_controller().stop(); + } +} + +void split_8_du_impl::add_ru(std::unique_ptr active_ru) +{ + ru = std::move(active_ru); + srsran_assert(ru, "Invalid Radio Unit"); + + ru_dl_rg_adapt.connect(ru->get_downlink_plane_handler()); + ru_ul_request_adapt.connect(ru->get_uplink_plane_handler()); +} + +void split_8_du_impl::add_dus(std::vector> active_du) +{ + du_list = std::move(active_du); + srsran_assert(!du_list.empty(), "Cannot set an empty DU list"); + + for (auto& du_obj : du_list) { + span upper_ptrs = du_obj->get_du_low_wrapper().get_du_low().get_all_upper_phys(); + for (auto* upper : upper_ptrs) { + // Make connections between DU and RU. + ru_ul_adapt.map_handler(upper->get_sector_id(), upper->get_rx_symbol_handler()); + ru_timing_adapt.map_handler(upper->get_sector_id(), upper->get_timing_handler()); + ru_error_adapt.map_handler(upper->get_sector_id(), upper->get_error_handler()); + } + } +} diff --git a/apps/units/flexible_du/split_8/split_8_du_impl.h b/apps/units/flexible_du/split_8/split_8_du_impl.h new file mode 100644 index 0000000000..ceb266628e --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_impl.h @@ -0,0 +1,62 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srsran/du/du.h" +#include "srsran/du/du_power_controller.h" +#include "srsran/du/du_wrapper.h" +#include "srsran/ru/ru_adapters.h" +#include +#include + +namespace srsran { + +class radio_unit; + +/// DU split 8 implementation. +class split_8_du_impl : public srs_du::du, public du_power_controller +{ +public: + explicit split_8_du_impl(unsigned nof_cells); + + // See interface for documentation. + du_power_controller& get_power_controller() override { return *this; } + + // See interface for documentation. + void start() override; + + // See interface for documentation. + void stop() override; + + /// Adds the given RU to this split 8 DU. + void add_ru(std::unique_ptr active_ru); + + /// Adds the given DUs to this split 8 DU. + void add_dus(std::vector> active_du); + + /// Getters to the adaptors. + upper_ru_ul_adapter& get_upper_ru_ul_adapter() { return ru_ul_adapt; } + upper_ru_timing_adapter& get_upper_ru_timing_adapter() { return ru_timing_adapt; } + upper_ru_error_adapter& get_upper_ru_error_adapter() { return ru_error_adapt; } + upper_ru_dl_rg_adapter& get_upper_ru_dl_rg_adapter() { return ru_dl_rg_adapt; } + upper_ru_ul_request_adapter& get_upper_ru_ul_request_adapter() { return ru_ul_request_adapt; } + +private: + upper_ru_ul_adapter ru_ul_adapt; + upper_ru_timing_adapter ru_timing_adapt; + upper_ru_error_adapter ru_error_adapt; + std::vector> du_list; + std::unique_ptr ru; + upper_ru_dl_rg_adapter ru_dl_rg_adapt; + upper_ru_ul_request_adapter ru_ul_request_adapt; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.cpp b/apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.cpp new file mode 100644 index 0000000000..1a1bb64b26 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.cpp @@ -0,0 +1,45 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_8_du_unit_cli11_schema.h" +#include "apps/units/flexible_du/du_high/du_high_config_cli11_schema.h" +#include "apps/units/flexible_du/du_low/du_low_config_cli11_schema.h" +#include "apps/units/flexible_du/fapi/fapi_config_cli11_schema.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_cli11_schema.h" +#include "split_8_du_unit_config.h" +#include "srsran/support/cli11_utils.h" + +using namespace srsran; + +void srsran::configure_cli11_with_split_8_du_unit_config_schema(CLI::App& app, split_8_du_unit_config& parsed_cfg) +{ + configure_cli11_with_du_high_config_schema(app, parsed_cfg.du_high_cfg); + configure_cli11_with_du_low_config_schema(app, parsed_cfg.du_low_cfg); + configure_cli11_with_fapi_config_schema(app, parsed_cfg.fapi_cfg); + configure_cli11_with_ru_sdr_config_schema(app, parsed_cfg.ru_cfg); +} + +void srsran::autoderive_split_8_du_parameters_after_parsing(CLI::App& app, split_8_du_unit_config& parsed_cfg) +{ + autoderive_du_high_parameters_after_parsing(app, parsed_cfg.du_high_cfg.config); + // Auto derive SDR parameters. + autoderive_ru_sdr_parameters_after_parsing(app, parsed_cfg.ru_cfg, parsed_cfg.du_high_cfg.config.cells_cfg.size()); + + // Auto derive DU low parameters. + const auto& cell = parsed_cfg.du_high_cfg.config.cells_cfg.front().cell; + nr_band band = cell.band ? cell.band.value() : band_helper::get_band_from_dl_arfcn(cell.dl_f_ref_arfcn); + bool is_blocking_mode_enabled = parsed_cfg.ru_cfg.device_driver == "zmq"; + + autoderive_du_low_parameters_after_parsing(app, + parsed_cfg.du_low_cfg, + band_helper::get_duplex_mode(band), + is_blocking_mode_enabled, + parsed_cfg.du_high_cfg.config.cells_cfg.size()); +} diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.h b/apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.h new file mode 100644 index 0000000000..d8ee05915b --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_cli11_schema.h @@ -0,0 +1,25 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "CLI/CLI11.hpp" + +namespace srsran { + +struct split_8_du_unit_config; + +/// Configures the given CLI11 application with the split 8 DU unit configuration schema. +void configure_cli11_with_split_8_du_unit_config_schema(CLI::App& app, split_8_du_unit_config& parsed_cfg); + +/// Auto derive split 8 DU parameters after the parsing. +void autoderive_split_8_du_parameters_after_parsing(CLI::App& app, split_8_du_unit_config& parsed_cfg); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_config.h b/apps/units/flexible_du/split_8/split_8_du_unit_config.h new file mode 100644 index 0000000000..06f62aa835 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_config.h @@ -0,0 +1,32 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_high/du_high_config.h" +#include "apps/units/flexible_du/du_low/du_low_config.h" +#include "apps/units/flexible_du/fapi/fapi_config.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config.h" + +namespace srsran { + +/// Split 8 DU unit configuration. +struct split_8_du_unit_config { + /// DU high configuration. + du_high_parsed_config du_high_cfg; + /// DU low configuration. + du_low_unit_config du_low_cfg; + /// FAPI configuration. + fapi_unit_config fapi_cfg; + /// Radio Unit configuration. + ru_sdr_unit_config ru_cfg; +}; + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_config_validator.cpp b/apps/units/flexible_du/split_8/split_8_du_unit_config_validator.cpp new file mode 100644 index 0000000000..ec21d3ecd4 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_config_validator.cpp @@ -0,0 +1,90 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_8_du_unit_config_validator.h" +#include "apps/units/flexible_du/du_high/du_high_config_validator.h" +#include "apps/units/flexible_du/du_low/du_low_config_validator.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_validator.h" +#include "srsran/ran/prach/prach_configuration.h" +#include "srsran/ran/prach/prach_preamble_information.h" + +using namespace srsran; + +static std::vector get_du_low_validation_dependencies(const du_high_unit_config& config) +{ + std::vector out_cfg(config.cells_cfg.size()); + + for (unsigned i = 0, e = config.cells_cfg.size(); i != e; ++i) { + du_low_prach_validation_config& out_cell = out_cfg[i]; + const du_high_unit_base_cell_config& in_cell = config.cells_cfg[i].cell; + + // Get PRACH info. + subcarrier_spacing common_scs = in_cell.common_scs; + prach_configuration prach_info = prach_configuration_get(frequency_range::FR1, + band_helper::get_duplex_mode(in_cell.band.value()), + in_cell.prach_cfg.prach_config_index.value()); + + // PRACH format type. + out_cell.format = prach_info.format; + + // Get preamble info. + prach_preamble_information preamble_info = + is_long_preamble(prach_info.format) + ? get_prach_preamble_long_info(prach_info.format) + : get_prach_preamble_short_info(prach_info.format, to_ra_subcarrier_spacing(common_scs), false); + + out_cell.prach_scs = preamble_info.scs; + out_cell.zero_correlation_zone = in_cell.prach_cfg.zero_correlation_zone; + out_cell.nof_prach_ports = in_cell.prach_cfg.ports.size(); + out_cell.nof_antennas_ul = in_cell.nof_antennas_ul; + } + + return out_cfg; +} + +static std::vector get_ru_sdr_validation_dependencies(const du_high_unit_config& config) +{ + std::vector out_cfg(config.cells_cfg.size()); + + for (unsigned i = 0, e = config.cells_cfg.size(); i != e; ++i) { + ru_sdr_cell_validation_config& out_cell = out_cfg[i]; + const du_high_unit_base_cell_config& in_cell = config.cells_cfg[i].cell; + + // Validates the sampling rate is compatible with the PRACH sequence. + out_cell.common_scs = in_cell.common_scs; + prach_configuration prach_info = prach_configuration_get(frequency_range::FR1, + band_helper::get_duplex_mode(in_cell.band.value()), + in_cell.prach_cfg.prach_config_index.value()); + out_cell.prach_format = prach_info.format; + out_cell.channel_bw_mhz = in_cell.channel_bw_mhz; + out_cell.dplx_mode = band_helper::get_duplex_mode(in_cell.band.value()); + out_cell.preamble_info = + is_long_preamble(prach_info.format) + ? get_prach_preamble_long_info(prach_info.format) + : get_prach_preamble_short_info(prach_info.format, to_ra_subcarrier_spacing(in_cell.common_scs), false); + } + + return out_cfg; +} +bool srsran::validate_split_8_du_unit_config(const split_8_du_unit_config& config, + const os_sched_affinity_bitmask& available_cpus) +{ + if (!validate_du_high_config(config.du_high_cfg.config, available_cpus)) { + return false; + } + + auto du_low_dependencies = get_du_low_validation_dependencies(config.du_high_cfg.config); + if (!validate_du_low_config(config.du_low_cfg, du_low_dependencies, available_cpus)) { + return false; + } + + auto ru_sdr_dependencies = get_ru_sdr_validation_dependencies(config.du_high_cfg.config); + return validate_ru_sdr_config(config.ru_cfg, ru_sdr_dependencies, available_cpus); +} diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_config_validator.h b/apps/units/flexible_du/split_8/split_8_du_unit_config_validator.h new file mode 100644 index 0000000000..080b736467 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_config_validator.h @@ -0,0 +1,21 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "split_8_du_unit_config.h" + +namespace srsran { + +/// Validates the given split 8 DU unit configuration. Returns true on success, false otherwise. +bool validate_split_8_du_unit_config(const split_8_du_unit_config& config, + const os_sched_affinity_bitmask& available_cpus); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.cpp b/apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.cpp new file mode 100644 index 0000000000..f9f37324fd --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.cpp @@ -0,0 +1,26 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "split_8_du_unit_config_yaml_writer.h" +#include "apps/units/flexible_du/du_high/du_high_config_yaml_writer.h" +#include "apps/units/flexible_du/du_low/du_low_config_yaml_writer.h" +#include "apps/units/flexible_du/fapi/fapi_config_yaml_writer.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_yaml_writer.h" +#include "split_8_du_unit_config.h" + +using namespace srsran; + +void srsran::fill_split_8_du_unit_config_in_yaml_schema(YAML::Node& node, const split_8_du_unit_config& config) +{ + fill_du_high_config_in_yaml_schema(node, config.du_high_cfg.config); + fill_du_low_config_in_yaml_schema(node, config.du_low_cfg); + fill_fapi_config_in_yaml_schema(node, config.fapi_cfg); + fill_ru_sdr_config_in_yaml_schema(node, config.ru_cfg); +} diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.h b/apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.h new file mode 100644 index 0000000000..da3b3e0287 --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_config_yaml_writer.h @@ -0,0 +1,22 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include + +namespace srsran { + +struct split_8_du_unit_config; + +/// Fills the given node with the split 8 DU configuration values. +void fill_split_8_du_unit_config_in_yaml_schema(YAML::Node& node, const split_8_du_unit_config& config); + +} // namespace srsran diff --git a/apps/units/flexible_du/split_8/split_8_du_unit_logger_registrator.h b/apps/units/flexible_du/split_8/split_8_du_unit_logger_registrator.h new file mode 100644 index 0000000000..9d10e62bcb --- /dev/null +++ b/apps/units/flexible_du/split_8/split_8_du_unit_logger_registrator.h @@ -0,0 +1,30 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "apps/units/flexible_du/du_high/du_high_logger_registrator.h" +#include "apps/units/flexible_du/du_low/du_low_logger_registrator.h" +#include "apps/units/flexible_du/fapi/fapi_logger_registrator.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_logger_registrator.h" +#include "split_8_du_unit_config.h" + +namespace srsran { + +/// Registers all the loggers for the DU split 8. +inline void register_split_8_du_loggers(const split_8_du_unit_config& config) +{ + register_du_high_loggers(config.du_high_cfg.config.loggers); + register_du_low_loggers(config.du_low_cfg.loggers); + register_fapi_loggers(config.fapi_cfg); + register_ru_sdr_logs(config.ru_cfg.loggers); +} + +} // namespace srsran diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp index 8edaf9704d..fecf9a3f2c 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_factory.cpp @@ -19,7 +19,7 @@ #include "apps/units/flexible_du/du_low/du_low_wrapper_config_helper.h" #include "apps/units/flexible_du/flexible_du_commands.h" #include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_factories.h" -#include "apps/units/flexible_du/split_8/ru_sdr_factories.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_factories.h" #include "dynamic_du_impl.h" #include "dynamic_du_translators.h" #include "dynamic_du_unit_config.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp index b35f4fea42..ee4bcf1dec 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_impl.cpp @@ -9,7 +9,6 @@ */ #include "dynamic_du_impl.h" - #include "srsran/du/du_low/du_low.h" #include "srsran/du/du_low/du_low_wrapper.h" #include "srsran/du/du_wrapper.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp index 99304f820b..907034db78 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_translators.cpp @@ -14,7 +14,7 @@ #include "apps/units/flexible_du/du_low/du_low_config_translator.h" #include "apps/units/flexible_du/fapi/fapi_config_translator.h" #include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_translator.h" -#include "apps/units/flexible_du/split_8/ru_sdr_config_translator.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_translator.h" #include "dynamic_du_unit_config.h" #include "srsran/du/du_cell_config.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp index 3bc09a73f0..e5db4a3b9f 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_cli11_schema.cpp @@ -13,7 +13,7 @@ #include "apps/units/flexible_du/du_low/du_low_config_cli11_schema.h" #include "apps/units/flexible_du/fapi/fapi_config_cli11_schema.h" #include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_cli11_schema.h" -#include "apps/units/flexible_du/split_8/ru_sdr_config_cli11_schema.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_cli11_schema.h" #include "apps/units/flexible_du/support/cli11_cpu_affinities_parser_helper.h" #include "dynamic_du_unit_config.h" #include "srsran/support/cli11_utils.h" diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h index f5b75df5f7..6bcb08b69c 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config.h @@ -14,7 +14,7 @@ #include "apps/units/flexible_du/du_low/du_low_config.h" #include "apps/units/flexible_du/fapi/fapi_config.h" #include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config.h" -#include "apps/units/flexible_du/split_8/ru_sdr_config.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config.h" #include namespace srsran { diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp index 9548bf2ca5..2d48bd9334 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_validator.cpp @@ -12,7 +12,7 @@ #include "apps/units/flexible_du/du_high/du_high_config_validator.h" #include "apps/units/flexible_du/du_low/du_low_config_validator.h" #include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_validator.h" -#include "apps/units/flexible_du/split_8/ru_sdr_config_validator.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_validator.h" #include "srsran/ran/prach/prach_configuration.h" using namespace srsran; diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp index 910392ce9b..ed1db0d31d 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_config_yaml_writer.cpp @@ -13,7 +13,7 @@ #include "apps/units/flexible_du/du_low/du_low_config_yaml_writer.h" #include "apps/units/flexible_du/fapi/fapi_config_yaml_writer.h" #include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_config_yaml_writer.h" -#include "apps/units/flexible_du/split_8/ru_sdr_config_yaml_writer.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_config_yaml_writer.h" #include "dynamic_du_unit_config.h" using namespace srsran; diff --git a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h index 159bbb15cf..5db3fbd86d 100644 --- a/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h +++ b/apps/units/flexible_du/split_dynamic/dynamic_du_unit_logger_registrator.h @@ -14,7 +14,7 @@ #include "apps/units/flexible_du/du_low/du_low_logger_registrator.h" #include "apps/units/flexible_du/fapi/fapi_logger_registrator.h" #include "apps/units/flexible_du/split_7_2/helpers/ru_ofh_logger_registrator.h" -#include "apps/units/flexible_du/split_8/ru_sdr_logger_registrator.h" +#include "apps/units/flexible_du/split_8/helpers/ru_sdr_logger_registrator.h" #include "dynamic_du_unit_config.h" namespace srsran { From 58d89d0e3fcf14241da077e704198e2f08891073 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Wed, 25 Sep 2024 19:07:10 +0200 Subject: [PATCH 130/174] sched: set max. PRB for slices taking into account cell PRBs --- lib/scheduler/slicing/slice_scheduler.cpp | 21 ++++++-- lib/scheduler/slicing/slice_scheduler.h | 2 +- .../ue_scheduling/ue_scheduler_impl.cpp | 2 +- .../policy/scheduler_policy_test.cpp | 6 +-- .../slicing/slice_scheduler_test.cpp | 50 +++++++++---------- 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/lib/scheduler/slicing/slice_scheduler.cpp b/lib/scheduler/slicing/slice_scheduler.cpp index c9471c47d8..c2b8d6dc30 100644 --- a/lib/scheduler/slicing/slice_scheduler.cpp +++ b/lib/scheduler/slicing/slice_scheduler.cpp @@ -25,20 +25,26 @@ slice_scheduler::slice_scheduler(const cell_configuration& cell_cfg_, ue_reposit // DRB slice). slices.reserve(cell_cfg.rrm_policy_members.size() + 2); + // NOTE: We assume nof. CRBs in a cell for both DL and UL are same. + const unsigned cell_max_rbs = cell_cfg.dl_cfg_common.init_dl_bwp.generic_params.crbs.length(); + // Create RAN slice instances. // Default SRB slice. // NOTE: We set \c min_prb for default SRB slice to maximum nof. PRBs of a UE carrier to give maximum priority to this // slice. - slices.emplace_back(default_srb_ran_slice_id, cell_cfg, slice_rrm_policy_config{.min_prb = MAX_NOF_PRBS}); + slices.emplace_back( + default_srb_ran_slice_id, cell_cfg, slice_rrm_policy_config{.min_prb = cell_max_rbs, .max_prb = cell_max_rbs}); slices.back().policy = create_scheduler_strategy(cell_cfg.expert_cfg.ue); // Default DRB slice. - slices.emplace_back(default_drb_ran_slice_id, cell_cfg, slice_rrm_policy_config{}); + slices.emplace_back(default_drb_ran_slice_id, cell_cfg, slice_rrm_policy_config{.max_prb = cell_max_rbs}); slices.back().policy = create_scheduler_strategy(cell_cfg.expert_cfg.ue); // NOTE: RAN slice IDs 0 and 1 are reserved for default SRB and default DRB slice respectively. ran_slice_id_t id_count{2}; // Configured RRM policy members. for (const slice_rrm_policy_config& rrm : cell_cfg.rrm_policy_members) { slices.emplace_back(id_count, cell_cfg, rrm); + // Adjust maximum PRBs per slice based on the number of PRBs in a cell. + slices.back().inst.cfg.max_prb = std::min(slices.back().inst.cfg.max_prb, cell_max_rbs); // Set policy scheduler based on slice configuration. scheduler_ue_expert_config slice_scheduler_ue_expert_cfg{cell_cfg.expert_cfg.ue}; slice_scheduler_ue_expert_cfg.strategy_cfg = rrm.policy_sched_cfg; @@ -59,7 +65,7 @@ slice_scheduler::slice_scheduler(const cell_configuration& cell_cfg_, ue_reposit } } -void slice_scheduler::slot_indication(slot_point slot_tx) +void slice_scheduler::slot_indication(slot_point slot_tx, const cell_resource_allocator& res_grid) { // If there are skipped slots, handle them. if ((current_slot + 1) != slot_tx) { @@ -94,6 +100,15 @@ void slice_scheduler::slot_indication(slot_point slot_tx) cell_cfg.ul_cfg_common.init_ul_bwp.pusch_cfg_common.value().pusch_td_alloc_list; for (const unsigned pusch_td_res_idx : valid_pusch_td_list_per_slot[slot_tx.to_uint() % valid_pusch_td_list_per_slot.size()]) { + const cell_slot_resource_allocator& pusch_alloc = res_grid[pusch_time_domain_list[pusch_td_res_idx].k2]; + const crb_bitmap pusch_used_crbs = + pusch_alloc.ul_res_grid.used_crbs(cell_cfg.ul_cfg_common.init_ul_bwp.generic_params.scs, + cell_cfg.ul_cfg_common.init_ul_bwp.generic_params.crbs, + pusch_time_domain_list[pusch_td_res_idx].symbols); + if (pusch_used_crbs.all()) { + // No more RBs left to allocated so skip adding slice candidate. + continue; + } slot_point pusch_slot = slot_tx + pusch_time_domain_list[pusch_td_res_idx].k2; unsigned pusch_rb_count = slice.inst.pusch_rb_count_per_slot[pusch_slot.to_uint() % slice.inst.pusch_rb_count_per_slot.size()]; diff --git a/lib/scheduler/slicing/slice_scheduler.h b/lib/scheduler/slicing/slice_scheduler.h index 62b5e1ac63..a71c251e6a 100644 --- a/lib/scheduler/slicing/slice_scheduler.h +++ b/lib/scheduler/slicing/slice_scheduler.h @@ -28,7 +28,7 @@ class slice_scheduler slice_scheduler(const cell_configuration& cell_cfg_, ue_repository& ues_); /// Reset the state of the slices. - void slot_indication(slot_point slot_tx); + void slot_indication(slot_point slot_tx, const cell_resource_allocator& res_grid); /// Update the state of the slice with the provided UE configs. void add_ue(du_ue_index_t ue_idx); diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp index 52c5e20d3c..2ad943cc6e 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp @@ -51,7 +51,7 @@ void ue_scheduler_impl::run_sched_strategy(slot_point slot_tx, du_cell_index_t c } // Update slice context and compute slice priorities. - cells[cell_index]->slice_sched.slot_indication(slot_tx); + cells[cell_index]->slice_sched.slot_indication(slot_tx, ue_res_grid_view.get_grid(cell_index)); // Perform round-robin prioritization of UL and DL scheduling. This gives unfair preference to DL over UL. This is // done to avoid the issue of sending wrong DAI value in DCI format 0_1 to UE while the PDSCH is allocated diff --git a/tests/unittests/scheduler/policy/scheduler_policy_test.cpp b/tests/unittests/scheduler/policy/scheduler_policy_test.cpp index a2827ed71f..775877df30 100644 --- a/tests/unittests/scheduler/policy/scheduler_policy_test.cpp +++ b/tests/unittests/scheduler/policy/scheduler_policy_test.cpp @@ -66,15 +66,15 @@ class base_scheduler_policy_test { logger.set_context(next_slot.sfn(), next_slot.slot_index()); - grid_alloc.slot_indication(next_slot); - slice_sched.slot_indication(next_slot); - res_grid.slot_indication(next_slot); + grid_alloc.slot_indication(next_slot); cell_harqs.slot_indication(next_slot); pdcch_alloc.slot_indication(next_slot); pucch_alloc.slot_indication(next_slot); uci_alloc.slot_indication(next_slot); + slice_sched.slot_indication(next_slot, ue_res_grid.get_grid(to_du_cell_index(0))); + if (cell_cfg.is_dl_enabled(next_slot)) { auto dl_slice_candidate = slice_sched.get_next_dl_candidate(); while (dl_slice_candidate.has_value()) { diff --git a/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp b/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp index 14787d2ffd..f1f9bfef1d 100644 --- a/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp +++ b/tests/unittests/scheduler/slicing/slice_scheduler_test.cpp @@ -42,6 +42,13 @@ class slice_scheduler_test ~slice_scheduler_test() { srslog::flush(); } + void run_slot() + { + dummy_alloc.slot_indication(current_slot); + slice_sched.slot_indication(current_slot, dummy_alloc); + ++current_slot; + } + const ue_configuration* add_ue(const sched_ue_creation_request_message& req) { const ue_configuration* ue_cfg = test_cfg.add_ue(req); @@ -61,7 +68,8 @@ class slice_scheduler_test std::make_unique(harq_timeout_handler)}; ue_repository ues; - slice_scheduler slice_sched{cell_cfg, ues}; + cell_resource_allocator dummy_alloc{cell_cfg}; + slice_scheduler slice_sched{cell_cfg, ues}; public: slot_point current_slot{to_numerology_value(cell_cfg.dl_cfg_common.freq_info_dl.scs_carrier_list.back().scs), 0}; @@ -83,15 +91,11 @@ class default_slice_scheduler_test : public slice_scheduler_test, public ::testi TEST_F(default_slice_scheduler_test, if_no_rrm_policy_cfg_exists_then_only_default_slices_are_created) { ASSERT_EQ(slice_sched.nof_slices(), 2); - ASSERT_EQ(slice_sched.slice_config(ran_slice_id_t{0}).min_prb, MAX_NOF_PRBS); - ASSERT_EQ(slice_sched.slice_config(ran_slice_id_t{0}).max_prb, MAX_NOF_PRBS); - ASSERT_EQ(slice_sched.slice_config(ran_slice_id_t{1}).min_prb, 0); - ASSERT_EQ(slice_sched.slice_config(ran_slice_id_t{1}).max_prb, MAX_NOF_PRBS); } TEST_F(default_slice_scheduler_test, when_no_lcid_exists_then_default_slice_is_not_a_candidate) { - slice_sched.slot_indication(current_slot); + run_slot(); auto next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_FALSE(next_dl_slice.has_value()); @@ -105,8 +109,7 @@ TEST_F(default_slice_scheduler_test, when_lcid_is_part_of_default_slice_then_def ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); for (unsigned count = 0, e = 10; count != e; ++count) { - ++current_slot; - slice_sched.slot_indication(current_slot); + run_slot(); auto next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_TRUE(next_dl_slice.has_value()); @@ -128,7 +131,7 @@ TEST_F(default_slice_scheduler_test, when_candidate_instance_goes_out_of_scope_then_it_stops_being_a_candidate_for_the_same_slot) { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); auto next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_TRUE(next_dl_slice.has_value()); @@ -146,11 +149,11 @@ TEST_F(default_slice_scheduler_test, when_candidate_instance_goes_out_of_scope_t { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); auto next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_TRUE(next_dl_slice.has_value()); - slice_sched.slot_indication(current_slot); + run_slot(); next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_TRUE(next_dl_slice.has_value()); ASSERT_EQ(next_dl_slice->id(), ran_slice_id_t{0}); @@ -159,7 +162,7 @@ TEST_F(default_slice_scheduler_test, when_candidate_instance_goes_out_of_scope_t TEST_F(default_slice_scheduler_test, when_grant_gets_allocated_then_number_of_available_rbs_decreases) { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); auto next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -191,7 +194,7 @@ TEST_F(default_slice_scheduler_test, returns_only_dl_pending_bytes_of_bearers_be ind.bs = srb_pending_bytes; this->ues[ue_idx].handle_dl_buffer_state_indication(ind); - slice_sched.slot_indication(current_slot); + run_slot(); // Default SRB slice has very high priority. auto next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -234,8 +237,7 @@ TEST_F(default_slice_scheduler_test, returns_only_ul_pending_bytes_of_bearers_be this->ues[ue_idx].handle_bsr_indication(msg); for (unsigned count = 0, e = 10; count != e; ++count) { - ++current_slot; - slice_sched.slot_indication(current_slot); + run_slot(); auto next_ul_slice = slice_sched.get_next_ul_candidate(); if (next_ul_slice.has_value()) { @@ -294,7 +296,7 @@ class rb_ratio_slice_scheduler_test : public slice_scheduler_test, public ::test TEST_F(rb_ratio_slice_scheduler_test, when_slice_with_min_rb_has_ues_then_it_is_the_first_candidate) { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); // Default SRB slice has very high priority. auto next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -308,7 +310,7 @@ TEST_F(rb_ratio_slice_scheduler_test, when_slice_with_min_rb_has_ues_then_it_is_ TEST_F(rb_ratio_slice_scheduler_test, when_slice_rb_ratios_are_min_bounded_then_remaining_rbs_is_min_bounded) { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); // Default SRB slice has very high priority. auto next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -324,7 +326,7 @@ TEST_F(rb_ratio_slice_scheduler_test, when_slice_with_min_rb_is_partially_scheduled_then_it_is_never_a_candidate_again_for_the_same_slot) { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); // Default SRB slice has very high priority. auto next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -344,7 +346,7 @@ TEST_F(rb_ratio_slice_scheduler_test, when_slice_with_min_rb_is_allocated_until_min_rb_then_it_can_still_a_candidate_until_max_rb_is_reached) { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); // Default SRB slice has very high priority. auto next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -369,7 +371,7 @@ TEST_F(rb_ratio_slice_scheduler_test, when_candidates_are_scheduled_in_a_slot_then_priorities_are_recomputed_in_a_new_slot) { ASSERT_NE(this->add_ue(to_du_ue_index(0)), nullptr); - slice_sched.slot_indication(current_slot); + run_slot(); // Default SRB slice has very high priority. auto next_dl_slice = slice_sched.get_next_dl_candidate(); @@ -383,7 +385,7 @@ TEST_F(rb_ratio_slice_scheduler_test, ASSERT_FALSE(next_dl_slice.has_value()); // New slot and priorities are reestablished. - slice_sched.slot_indication(current_slot); + run_slot(); next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_EQ(next_dl_slice->id(), drb1_slice_id); ASSERT_EQ(next_dl_slice->remaining_rbs(), MIN_SLICE_RB); @@ -411,8 +413,7 @@ TEST_F(rb_ratio_slice_scheduler_test, unsigned slice_3_count = 0; unsigned slice_2_count = 0; for (unsigned count = 0; count != max_nof_slots; ++count) { - ++current_slot; - slice_sched.slot_indication(current_slot); + run_slot(); // Either default SRB slice (Slice 0) or DRB1 slice (Slice 2) or DRB2 slice (Slice 3) is selected first since both // have minRBs > 0. @@ -461,8 +462,7 @@ TEST_F(srb_prioritization_slice_scheduler_test, schedules_default_srb_slice_firs ASSERT_NE(this->add_ue(to_du_ue_index(1)), nullptr); for (unsigned count = 0, e = 10; count != e; ++count) { - ++current_slot; - slice_sched.slot_indication(current_slot); + run_slot(); auto next_dl_slice = slice_sched.get_next_dl_candidate(); ASSERT_TRUE(next_dl_slice.has_value()); From d42597ccc6347c27bbc826179979f7fdbdac4200 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Thu, 26 Sep 2024 11:01:37 +0200 Subject: [PATCH 131/174] units: removed module namespace from the application units PCAP factory --- apps/cu/cu.cpp | 6 ++---- apps/du/du.cpp | 3 +-- apps/gnb/gnb.cpp | 9 +++------ apps/units/cu_cp/pcap_factory.h | 13 +++++++------ apps/units/cu_up/pcap_factory.h | 8 ++++---- apps/units/flexible_du/du_high/pcap_factory.h | 12 ++++-------- 6 files changed, 21 insertions(+), 30 deletions(-) diff --git a/apps/cu/cu.cpp b/apps/cu/cu.cpp index 6a611795bf..3d049d047d 100644 --- a/apps/cu/cu.cpp +++ b/apps/cu/cu.cpp @@ -264,10 +264,8 @@ int main(int argc, char** argv) cu_worker_manager workers{cu_cfg, cu_cp_config.pcap_cfg, cu_up_config.pcap_cfg, cu_up_config.gtpu_queue_size}; // Create layer specific PCAPs. - srsran::modules::cu_cp::cu_cp_dlt_pcaps cu_cp_dlt_pcaps = - modules::cu_cp::create_dlt_pcap(cu_cp_config.pcap_cfg, *workers.get_executor_getter()); - srsran::modules::cu_up::cu_up_dlt_pcaps cu_up_dlt_pcaps = - modules::cu_up::create_dlt_pcaps(cu_up_config.pcap_cfg, *workers.get_executor_getter()); + cu_cp_dlt_pcaps cu_cp_dlt_pcaps = create_cu_cp_dlt_pcap(cu_cp_config.pcap_cfg, *workers.get_executor_getter()); + cu_up_dlt_pcaps cu_up_dlt_pcaps = create_cu_up_dlt_pcaps(cu_up_config.pcap_cfg, *workers.get_executor_getter()); // Create IO broker. const auto& low_prio_cpu_mask = cu_cfg.expert_execution_cfg.affinities.low_priority_cpu_cfg.mask; diff --git a/apps/du/du.cpp b/apps/du/du.cpp index cebba0811a..cda223e9ad 100644 --- a/apps/du/du.cpp +++ b/apps/du/du.cpp @@ -258,8 +258,7 @@ int main(int argc, char** argv) io_broker_config io_broker_cfg(low_prio_cpu_mask); std::unique_ptr epoll_broker = create_io_broker(io_broker_type::epoll, io_broker_cfg); - srsran::modules::flexible_du::du_pcaps du_pcaps = - modules::flexible_du::create_pcaps(du_app_unit->get_du_high_unit_config().pcaps, workers); + flexible_du_pcaps du_pcaps = create_du_pcaps(du_app_unit->get_du_high_unit_config().pcaps, workers); // Instantiate F1-C client gateway. std::unique_ptr f1c_gw = create_f1c_client_gateway( diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index bbb60d487e..c89bfd73d0 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -339,12 +339,9 @@ int main(int argc, char** argv) // We disable one accordingly. cu_up_config.pcap_cfg.disable_e1_pcaps(); du_app_unit->get_du_high_unit_config().pcaps.disable_f1_pcaps(); - srsran::modules::cu_cp::cu_cp_dlt_pcaps cu_cp_dlt_pcaps = - modules::cu_cp::create_dlt_pcap(cu_cp_config.pcap_cfg, *workers.get_executor_getter()); - srsran::modules::cu_up::cu_up_dlt_pcaps cu_up_dlt_pcaps = - modules::cu_up::create_dlt_pcaps(cu_up_config.pcap_cfg, *workers.get_executor_getter()); - srsran::modules::flexible_du::du_pcaps du_pcaps = - modules::flexible_du::create_pcaps(du_app_unit->get_du_high_unit_config().pcaps, workers); + cu_cp_dlt_pcaps cu_cp_dlt_pcaps = create_cu_cp_dlt_pcap(cu_cp_config.pcap_cfg, *workers.get_executor_getter()); + cu_up_dlt_pcaps cu_up_dlt_pcaps = create_cu_up_dlt_pcaps(cu_up_config.pcap_cfg, *workers.get_executor_getter()); + flexible_du_pcaps du_pcaps = create_du_pcaps(du_app_unit->get_du_high_unit_config().pcaps, workers); std::unique_ptr f1c_gw = create_f1c_local_connector(f1c_local_connector_config{*cu_cp_dlt_pcaps.f1ap}); diff --git a/apps/units/cu_cp/pcap_factory.h b/apps/units/cu_cp/pcap_factory.h index feb01b08b2..ebd4f54007 100644 --- a/apps/units/cu_cp/pcap_factory.h +++ b/apps/units/cu_cp/pcap_factory.h @@ -14,13 +14,14 @@ #include "apps/units/cu_cp/cu_cp_unit_pcap_config.h" #include "srsran/pcap/dlt_pcap.h" -namespace srsran::modules::cu_cp { +namespace srsran { struct cu_cp_dlt_pcaps { std::unique_ptr ngap; std::unique_ptr f1ap; std::unique_ptr e1ap; - void close() + + void close() { ngap.reset(); f1ap.reset(); @@ -28,9 +29,9 @@ struct cu_cp_dlt_pcaps { } }; -/// Creates the DLT PCAP of the CU-CP. -inline cu_cp_dlt_pcaps create_dlt_pcap(const cu_cp_unit_pcap_config& pcap_cfg, - worker_manager_executor_getter& exec_getter) +/// Creates the DLT PCAPs of the CU-CP. +inline cu_cp_dlt_pcaps create_cu_cp_dlt_pcap(const cu_cp_unit_pcap_config& pcap_cfg, + worker_manager_executor_getter& exec_getter) { cu_cp_dlt_pcaps pcaps; pcaps.ngap = pcap_cfg.ngap.enabled ? create_ngap_pcap(pcap_cfg.ngap.filename, exec_getter.get_executor("pcap_exec")) @@ -42,4 +43,4 @@ inline cu_cp_dlt_pcaps create_dlt_pcap(const cu_cp_unit_pcap_config& pcap_cfg, return pcaps; } -} // namespace srsran::modules::cu_cp +} // namespace srsran diff --git a/apps/units/cu_up/pcap_factory.h b/apps/units/cu_up/pcap_factory.h index c78e4018dd..ad4f0489a3 100644 --- a/apps/units/cu_up/pcap_factory.h +++ b/apps/units/cu_up/pcap_factory.h @@ -14,7 +14,7 @@ #include "apps/units/cu_up/cu_up_unit_pcap_config.h" #include "srsran/pcap/dlt_pcap.h" -namespace srsran::modules::cu_up { +namespace srsran { struct cu_up_dlt_pcaps { std::unique_ptr n3; @@ -29,8 +29,8 @@ struct cu_up_dlt_pcaps { }; /// Creates the DLT PCAPs of the CU-UP. -inline cu_up_dlt_pcaps create_dlt_pcaps(const cu_up_unit_pcap_config& pcap_cfg, - worker_manager_executor_getter& exec_getter) +inline cu_up_dlt_pcaps create_cu_up_dlt_pcaps(const cu_up_unit_pcap_config& pcap_cfg, + worker_manager_executor_getter& exec_getter) { cu_up_dlt_pcaps pcaps; @@ -46,4 +46,4 @@ inline cu_up_dlt_pcaps create_dlt_pcaps(const cu_up_unit_pcap_config& pcap_cfg return pcaps; } -} // namespace srsran::modules::cu_up +} // namespace srsran diff --git a/apps/units/flexible_du/du_high/pcap_factory.h b/apps/units/flexible_du/du_high/pcap_factory.h index 39889dd693..2cf4999b0f 100644 --- a/apps/units/flexible_du/du_high/pcap_factory.h +++ b/apps/units/flexible_du/du_high/pcap_factory.h @@ -16,10 +16,8 @@ #include "srsran/pcap/rlc_pcap.h" namespace srsran { -namespace modules { -namespace flexible_du { -struct du_pcaps { +struct flexible_du_pcaps { // DLT PCAPs std::unique_ptr f1ap; std::unique_ptr f1u; @@ -38,10 +36,10 @@ struct du_pcaps { } }; -/// Creates the DLT PCAP of the DU. -inline du_pcaps create_pcaps(const du_high_unit_pcap_config& pcap_cfg, worker_manager& workers) +/// Creates the PCAPs of the DU. +inline flexible_du_pcaps create_du_pcaps(const du_high_unit_pcap_config& pcap_cfg, worker_manager& workers) { - du_pcaps pcaps; + flexible_du_pcaps pcaps; pcaps.f1ap = pcap_cfg.f1ap.enabled ? create_f1ap_pcap(pcap_cfg.f1ap.filename, workers.get_executor("pcap_exec")) : create_null_dlt_pcap(); @@ -73,6 +71,4 @@ inline du_pcaps create_pcaps(const du_high_unit_pcap_config& pcap_cfg, worker_ma return pcaps; } -} // namespace flexible_du -} // namespace modules } // namespace srsran From e78f34876deff9dc2b56430eb8279734fd4b3e34 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Tue, 24 Sep 2024 15:25:43 +0200 Subject: [PATCH 132/174] sched: remove explicit step of scheduling UEs with SR indication from RR scheduler --- lib/scheduler/policy/scheduler_time_rr.cpp | 27 +++++-------------- .../policy/scheduler_policy_test.cpp | 19 +++++++++---- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/lib/scheduler/policy/scheduler_time_rr.cpp b/lib/scheduler/policy/scheduler_time_rr.cpp index 34a26d0a31..a2b37ea74e 100644 --- a/lib/scheduler/policy/scheduler_time_rr.cpp +++ b/lib/scheduler/policy/scheduler_time_rr.cpp @@ -336,15 +336,11 @@ static alloc_result alloc_ul_retxs(const slice_ue_repository& ue_db, /// Allocate UE PUSCH grant for new transmissions. static alloc_result alloc_ul_ue_newtx(const slice_ue& u, ue_pusch_allocator& pusch_alloc, - bool schedule_sr_only, srslog::basic_logger& logger, std::optional ul_new_tx_max_nof_rbs_per_ue_per_slot = {}) { unsigned pending_newtx_bytes = 0; - if (schedule_sr_only and not u.has_pending_sr()) { - return {alloc_status::skip_ue}; - } - pending_newtx_bytes = u.pending_ul_newtx_bytes(); + pending_newtx_bytes = u.pending_ul_newtx_bytes(); if (pending_newtx_bytes == 0) { return {alloc_status::skip_ue}; } @@ -426,31 +422,20 @@ void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc, return; } - // Prioritize UEs with pending SRs. - const unsigned ul_new_tx_max_nof_rbs_per_ue_per_slot = - compute_max_nof_rbs_per_ue_per_slot(ues, false, res_grid, expert_cfg, max_rbs); - // First, schedule UEs with pending SR. - auto sr_ue_function = [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { - return alloc_ul_ue_newtx(u, pusch_alloc, true, logger, ul_new_tx_max_nof_rbs_per_ue_per_slot); - }; - auto result = round_robin_apply(ues, next_ul_ue_index, sr_ue_function); - next_ul_ue_index = result.first; - if (result.second == alloc_status::skip_slot) { - return; - } - - // Second, schedule UEs with re-transmissions. + // First, schedule UEs with re-transmissions. auto retx_result = alloc_ul_retxs(ues, pusch_alloc, slice_id, harq_pending_retx_list); if (retx_result.status == alloc_status::skip_slot) { return; } // Then, schedule UEs with new transmissions. + const unsigned ul_new_tx_max_nof_rbs_per_ue_per_slot = + compute_max_nof_rbs_per_ue_per_slot(ues, false, res_grid, expert_cfg, max_rbs); if (ul_new_tx_max_nof_rbs_per_ue_per_slot > 0) { auto data_tx_ue_function = [this, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const slice_ue& u) { - return alloc_ul_ue_newtx(u, pusch_alloc, false, logger, ul_new_tx_max_nof_rbs_per_ue_per_slot); + return alloc_ul_ue_newtx(u, pusch_alloc, logger, ul_new_tx_max_nof_rbs_per_ue_per_slot); }; - result = round_robin_apply(ues, next_ul_ue_index, data_tx_ue_function); + auto result = round_robin_apply(ues, next_ul_ue_index, data_tx_ue_function); next_ul_ue_index = result.first; } } diff --git a/tests/unittests/scheduler/policy/scheduler_policy_test.cpp b/tests/unittests/scheduler/policy/scheduler_policy_test.cpp index 775877df30..b406134bfc 100644 --- a/tests/unittests/scheduler/policy/scheduler_policy_test.cpp +++ b/tests/unittests/scheduler/policy/scheduler_policy_test.cpp @@ -134,12 +134,21 @@ class base_scheduler_policy_test sched_ue_creation_request_message req = test_helpers::create_default_sched_ue_creation_request(); req.ue_index = ue_index; req.crnti = rnti; - auto default_lc_cfg = config_helpers::create_default_logical_channel_config(uint_to_lcid(0)); - default_lc_cfg.lc_group = lcg_id; - req.cfg.lc_config_list.emplace(); + // Set LCG ID for SRBs provided in the LCIDs to activate list. + for (auto& lc_cfg : *req.cfg.lc_config_list) { + if (lc_cfg.lcid < lcid_t::LCID_SRB2 and + std::find(lcids_to_activate.begin(), lcids_to_activate.end(), lc_cfg.lcid) != lcids_to_activate.end()) { + lc_cfg.lc_group = lcg_id; + } + } + auto default_lc_cfg = config_helpers::create_default_logical_channel_config(uint_to_lcid(0)); + default_lc_cfg.lc_group = lcg_id; + // Add DRBs if any in the LCIDs to activate list. for (lcid_t lcid : lcids_to_activate) { - default_lc_cfg.lcid = lcid; - req.cfg.lc_config_list->push_back(default_lc_cfg); + if (lcid >= lcid_t::LCID_SRB2) { + default_lc_cfg.lcid = lcid; + req.cfg.lc_config_list->push_back(default_lc_cfg); + } } return req; } From e5729d107db80c2062895e4810a8d1a0b910ff24 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Thu, 26 Sep 2024 17:00:18 +0200 Subject: [PATCH 133/174] sched: fix the value of number of slots per frame stored in cell configuration --- lib/scheduler/config/cell_configuration.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/scheduler/config/cell_configuration.cpp b/lib/scheduler/config/cell_configuration.cpp index e5a6d687cb..03fdb8d56c 100644 --- a/lib/scheduler/config/cell_configuration.cpp +++ b/lib/scheduler/config/cell_configuration.cpp @@ -25,7 +25,8 @@ cell_configuration::cell_configuration(const scheduler_expert_config& pci(msg.pci), nof_dl_prbs(get_max_Nprb(msg.dl_carrier.carrier_bw_mhz, msg.scs_common, frequency_range::FR1)), nof_ul_prbs(get_max_Nprb(msg.ul_carrier.carrier_bw_mhz, msg.scs_common, frequency_range::FR1)), - nof_slots_per_frame(get_nof_slots_per_subframe(msg.dl_cfg_common.init_dl_bwp.generic_params.scs)), + nof_slots_per_frame(get_nof_slots_per_subframe(msg.dl_cfg_common.init_dl_bwp.generic_params.scs) * + NOF_SUBFRAMES_PER_FRAME), dl_cfg_common(msg.dl_cfg_common), ul_cfg_common(msg.ul_cfg_common), tdd_cfg_common(msg.tdd_ul_dl_cfg_common), From 25b84b8034b32ad2585cd428fcd7d72db0be7097 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 25 Sep 2024 19:05:56 +0200 Subject: [PATCH 134/174] ran: add precoding information in DCI 0_1 ran: review DCI packing related ran: review doc --- include/srsran/ran/pdcch/dci_packing.h | 4 +- lib/ran/pdcch/dci_packing.cpp | 129 ++++++++++++++++-- .../unittests/ran/pdcch/dci_packing_test.cpp | 2 +- .../ran/pdcch/dci_packing_validator_test.cpp | 10 ++ 4 files changed, 132 insertions(+), 13 deletions(-) diff --git a/include/srsran/ran/pdcch/dci_packing.h b/include/srsran/ran/pdcch/dci_packing.h index 98fcc0a581..8fa3c2b8a6 100644 --- a/include/srsran/ran/pdcch/dci_packing.h +++ b/include/srsran/ran/pdcch/dci_packing.h @@ -896,8 +896,8 @@ struct dci_0_1_configuration { /// transform precoding is enabled or disabled, and the values of the higher layer parameters \e maxRank (see /// dci_size_config::max_rank) and \e codebookSubset (see dci_size_config::cb_subset). It is required for codebook /// based transmission with more than one antenna port, i.e., if \ref dci_size_config::cb_subset is set when computing - /// the DCI sizes. Otherwise, leave it unset. - std::optional precoding_info_nof_layers; + /// the DCI sizes. + unsigned precoding_info_nof_layers; /// \brief Antenna ports for PUSCH transmission - 2, 3, 4 or 5 bits. /// /// Indicates the antenna ports the UE must use to transmit the PUSCH and the corresponding DM-RS, as per TS38.212 diff --git a/lib/ran/pdcch/dci_packing.cpp b/lib/ran/pdcch/dci_packing.cpp index ca0fcf1a05..f97d6c6b1c 100644 --- a/lib/ran/pdcch/dci_packing.cpp +++ b/lib/ran/pdcch/dci_packing.cpp @@ -155,6 +155,98 @@ static unsigned freq_resource_assignment_size(resource_allocation res_alloca return freq_resource_size; } +// Computes the UL precoding information field size for DCI format 0_1 from TS38.212 Table 7.3.1.1.2-2. +static units::bits ul_precoding_info_size_4port(tx_scheme_codebook_subset codebook_subset) +{ + using namespace units::literals; + switch (codebook_subset) { + case tx_scheme_codebook_subset::fully_and_partial_and_non_coherent: + return 6_bits; + case tx_scheme_codebook_subset::partial_and_non_coherent: + return 5_bits; + case tx_scheme_codebook_subset::non_coherent: + default: + return 4_bits; + } +} + +// Computes the UL precoding information field size for DCI format 0_1 from TS38.212 Table 7.3.1.1.2-3. +static units::bits ul_precoding_info_size_4port_maxrank1(tx_scheme_codebook_subset codebook_subset) +{ + using namespace units::literals; + switch (codebook_subset) { + case tx_scheme_codebook_subset::fully_and_partial_and_non_coherent: + return 5_bits; + case tx_scheme_codebook_subset::partial_and_non_coherent: + return 4_bits; + case tx_scheme_codebook_subset::non_coherent: + default: + return 2_bits; + } +} + +// Computes the UL precoding information field size for DCI format 0_1 from TS38.212 Table 7.3.1.1.2-4. +static units::bits ul_precoding_info_size_2port(tx_scheme_codebook_subset codebook_subset) +{ + using namespace units::literals; + srsran_assert(codebook_subset != tx_scheme_codebook_subset::partial_and_non_coherent, + "Codebook subset \"partial and non-coherent\" is not supported with two ports.", + codebook_subset); + + if (codebook_subset == tx_scheme_codebook_subset::fully_and_partial_and_non_coherent) { + return 4_bits; + } + + return 2_bits; +} + +// Computes the UL precoding information field size for DCI format 0_1 from TS38.212 Table 7.3.1.1.2-5. +static units::bits ul_precoding_info_size_2port_maxrank1(tx_scheme_codebook_subset codebook_subset) +{ + using namespace units::literals; + srsran_assert(codebook_subset != tx_scheme_codebook_subset::partial_and_non_coherent, + "Codebook subset \"partial and non-coherent\" is not supported with two ports.", + codebook_subset); + + if (codebook_subset == tx_scheme_codebook_subset::fully_and_partial_and_non_coherent) { + return 3_bits; + } + + return 2_bits; +} + +// Computes the UL precoding information field size for DCI format 0_1. +static units::bits ul_precoding_info_size(bool tx_config_non_codebook, + unsigned nof_antenna_ports, + bool transform_precoding_enabled, + unsigned max_rank, + std::optional codebook_subset) +{ + using namespace units::literals; + + if (tx_config_non_codebook) { + return 0_bits; + } + + if (nof_antenna_ports == 1) { + return 0_bits; + } + + if ((nof_antenna_ports == 4) && (max_rank == 1)) { + return ul_precoding_info_size_4port_maxrank1(codebook_subset.value()); + } + + if (nof_antenna_ports == 4) { + return ul_precoding_info_size_4port(codebook_subset.value()); + } + + if ((nof_antenna_ports == 2) && (max_rank == 1)) { + return ul_precoding_info_size_2port_maxrank1(codebook_subset.value()); + } + + return ul_precoding_info_size_2port(codebook_subset.value()); +} + // Computes the UL antenna ports field size for a specific DM-RS configuration. static unsigned ul_dmrs_ports_size(dmrs_config_type dmrs_type, dmrs_max_length dmrs_len, bool transform_precoding) { @@ -343,7 +435,14 @@ static dci_0_1_size dci_f0_1_bits_before_padding(const dci_size_config& dci_conf sizes.total += sizes.srs_resource_indicator; // Precoding information and number of layers - 0, 1, 2, 3, 4, 5 or 6 bits. - // ... Not implemented. + if (dci_config.nof_srs_ports.has_value()) { + sizes.precoding_info_nof_layers = ul_precoding_info_size(dci_config.tx_config_non_codebook, + dci_config.nof_srs_ports.value(), + dci_config.transform_precoding_enabled, + dci_config.max_rank.value(), + dci_config.cb_subset); + sizes.total += sizes.precoding_info_nof_layers; + } // Antenna ports - 2, 3, 4 or 5 bits. sizes.antenna_ports = ul_ports_size(dci_config.pusch_dmrs_A_type, @@ -688,7 +787,9 @@ dci_sizes srsran::get_dci_sizes(const dci_size_config& config) dci_payload srsran::dci_0_0_c_rnti_pack(const dci_0_0_c_rnti_configuration& config) { - srsran_assert(config.payload_size.total.value() >= 12, "DCI payloads must be at least 12 bit long"); + srsran_assert(config.payload_size.total.value() >= 12, + "DCI total payload size is {}, it must be at least 12 bit long for DCI Format 0_0 and C-RNTI.", + config.payload_size.total); dci_payload payload; units::bits frequency_resource_nof_bits = config.payload_size.frequency_resource; @@ -769,7 +870,9 @@ dci_payload srsran::dci_0_0_c_rnti_pack(const dci_0_0_c_rnti_configuration& conf dci_payload srsran::dci_0_0_tc_rnti_pack(const dci_0_0_tc_rnti_configuration& config) { - srsran_assert(config.payload_size.total.value() >= 12, "DCI payloads must be at least 12 bit long"); + srsran_assert(config.payload_size.total.value() >= 12, + "DCI total payload size is {}, it must be at least 12 bit long for DCI Format 0_0 and TC-RNTI.", + config.payload_size.total); units::bits frequency_resource_nof_bits = config.payload_size.frequency_resource; dci_payload payload; @@ -846,7 +949,9 @@ dci_payload srsran::dci_0_0_tc_rnti_pack(const dci_0_0_tc_rnti_configuration& co dci_payload srsran::dci_1_0_c_rnti_pack(const dci_1_0_c_rnti_configuration& config) { - srsran_assert(config.payload_size.total.value() >= 12, "DCI payloads must be at least 12 bit long"); + srsran_assert(config.payload_size.total.value() >= 12, + "DCI total payload size is {}, it must be at least 12 bit long for DCI Format 1_0 and C-RNTI.", + config.payload_size.total); dci_payload payload; @@ -1051,12 +1156,12 @@ dci_payload srsran::dci_1_0_tc_rnti_pack(const dci_1_0_tc_rnti_configuration& co dci_payload srsran::dci_0_1_pack(const dci_0_1_configuration& config) { - srsran_assert(config.payload_size.total.value() >= 12, "DCI payloads must be at least 12 bit long"); + srsran_assert(config.payload_size.total.value() >= 12, + "DCI total payload size is {}, it must be at least 12 bit long for DCI Format 0_1.", + config.payload_size.total); // Assertions for unsupported fields. srsran_assert(!config.ul_sul_indicator.has_value(), "UL/SUL indicator field is not currently supported."); - srsran_assert(!config.precoding_info_nof_layers.has_value(), - "Precoding information and number of layers field is not currently supported."); srsran_assert(!config.ptrs_dmrs_association.has_value(), "PT-RS/DM-RS association field is not currently supported."); dci_payload payload; @@ -1156,9 +1261,7 @@ dci_payload srsran::dci_0_1_pack(const dci_0_1_configuration& config) payload.push_back(config.srs_resource_indicator, config.payload_size.srs_resource_indicator.value()); // Precoding information and number of layers - 0 to 6 bits. - if (config.precoding_info_nof_layers.has_value()) { - payload.push_back(config.precoding_info_nof_layers.value(), config.payload_size.precoding_info_nof_layers.value()); - } + payload.push_back(config.precoding_info_nof_layers, config.payload_size.precoding_info_nof_layers.value()); // Antenna ports for PUSCH transmission - 2, 3, 4 or 5 bits. payload.push_back(config.antenna_ports, config.payload_size.antenna_ports.value()); @@ -1603,6 +1706,12 @@ error_type srsran::validate_dci_size_config(const dci_size_config& return make_unexpected( fmt::format("The number of SRS ports {} is neither 1, 2, nor 4.", config.nof_srs_ports)); } + + // Codebook subset transmission with two ports does not support partial and non-coherent. + if ((config.nof_srs_ports.value() == 2) && + (config.cb_subset.value() == tx_scheme_codebook_subset::partial_and_non_coherent)) { + return make_unexpected("Codebook subset \"partial and non-coherent\" is not supported for 2 SRS ports."); + } } // PT-RS to DM-RS association is not currently supported. diff --git a/tests/unittests/ran/pdcch/dci_packing_test.cpp b/tests/unittests/ran/pdcch/dci_packing_test.cpp index a41a377017..518e814121 100644 --- a/tests/unittests/ran/pdcch/dci_packing_test.cpp +++ b/tests/unittests/ran/pdcch/dci_packing_test.cpp @@ -1137,7 +1137,7 @@ static dci_payload build_dci_0_1_expected(const dci_0_1_configuration& config) // Precoding information and number of layers. if (payload_size.precoding_info_nof_layers.value() != 0) { - expected_pack(expected, config.precoding_info_nof_layers.value(), payload_size.precoding_info_nof_layers.value()); + expected_pack(expected, config.precoding_info_nof_layers, payload_size.precoding_info_nof_layers.value()); } // Antenna ports for PUSCH transmission - 2, 3, 4 or 5 bits. diff --git a/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp b/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp index 321abed75f..c9d5f35086 100644 --- a/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp +++ b/tests/unittests/ran/pdcch/dci_packing_validator_test.cpp @@ -610,6 +610,16 @@ TEST_F(DciValidatorNonFallbackFixture, CodebookTransmissionInvalidConfig) test_validator(config, assert_message); } + { + dci_size_config config = get_base_dci_config(); + config.tx_config_non_codebook = false; + config.nof_srs_ports = 2; + config.cb_subset = tx_scheme_codebook_subset::partial_and_non_coherent; + std::string assert_message = + fmt::format("Codebook subset \"partial and non-coherent\" is not supported for 2 SRS ports."); + + test_validator(config, assert_message); + } { dci_size_config config = get_base_dci_config(); config.tx_config_non_codebook = false; From 55ea8c6cc4e0c8e670714814a090c92a1fedaa71 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 25 Sep 2024 19:22:05 +0200 Subject: [PATCH 135/174] sched: fix round-robin of slices when there are some slices with no data --- lib/scheduler/slicing/ran_slice_candidate.h | 2 +- lib/scheduler/slicing/ran_slice_instance.cpp | 8 ++++++ lib/scheduler/slicing/ran_slice_instance.h | 30 +++++++++++++++++++- lib/scheduler/slicing/slice_scheduler.cpp | 14 ++++----- lib/scheduler/slicing/slice_scheduler.h | 3 -- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/lib/scheduler/slicing/ran_slice_candidate.h b/lib/scheduler/slicing/ran_slice_candidate.h index c329e86732..f9976a8210 100644 --- a/lib/scheduler/slicing/ran_slice_candidate.h +++ b/lib/scheduler/slicing/ran_slice_candidate.h @@ -38,7 +38,7 @@ class common_ran_slice_candidate void store_grant(unsigned nof_rbs) { if constexpr (IsDl) { - inst->store_pdsch_grant(nof_rbs); + inst->store_pdsch_grant(nof_rbs, slot_tx); } else { inst->store_pusch_grant(nof_rbs, slot_tx); } diff --git a/lib/scheduler/slicing/ran_slice_instance.cpp b/lib/scheduler/slicing/ran_slice_instance.cpp index 6cb19c7184..c644a9dd76 100644 --- a/lib/scheduler/slicing/ran_slice_instance.cpp +++ b/lib/scheduler/slicing/ran_slice_instance.cpp @@ -32,6 +32,14 @@ void ran_slice_instance::slot_indication(slot_point slot_tx) for (unsigned count = 0; count < nof_slots_to_clear; ++count) { pusch_rb_count_per_slot[(slot_tx - 1 - count).to_uint() % pusch_rb_count_per_slot.size()] = 0; } + + // Reset last alloc slot if the different becomes to large, to avoid ambiguity. + if (last_pdsch_alloc_slot.valid() and slot_tx > last_pdsch_alloc_slot + MAX_SLOTS_SINCE_LAST_PXSCH) { + last_pdsch_alloc_slot.clear(); + } + if (last_pusch_alloc_slot.valid() and slot_tx > last_pusch_alloc_slot + MAX_SLOTS_SINCE_LAST_PXSCH) { + last_pdsch_alloc_slot.clear(); + } } void ran_slice_instance::skipped_slot_indication(slot_point prev_slot, slot_point current_slot) diff --git a/lib/scheduler/slicing/ran_slice_instance.h b/lib/scheduler/slicing/ran_slice_instance.h index e5da73582b..383b764ecb 100644 --- a/lib/scheduler/slicing/ran_slice_instance.h +++ b/lib/scheduler/slicing/ran_slice_instance.h @@ -22,6 +22,9 @@ namespace srsran { /// This class stores all the internal information relative to a RAN slice instantiation. class ran_slice_instance { + // Const for the max difference in number of slots between the current slot and the last allocation slot. + static constexpr unsigned MAX_SLOTS_SINCE_LAST_PXSCH = 512; + public: ran_slice_instance(ran_slice_id_t id_, const cell_configuration& cell_cfg_, const slice_rrm_policy_config& cfg_); @@ -33,12 +36,17 @@ class ran_slice_instance bool active() const { return not slice_ues.empty(); } /// Save PDSCH grant. - void store_pdsch_grant(unsigned crbs) { pdsch_rb_count += crbs; } + void store_pdsch_grant(unsigned crbs, slot_point pdsch_slot) + { + pdsch_rb_count += crbs; + last_pdsch_alloc_slot = pdsch_slot; + } /// Save PUSCH grant. void store_pusch_grant(unsigned crbs, slot_point pusch_slot) { pusch_rb_count_per_slot[pusch_slot.to_uint() % pusch_rb_count_per_slot.size()] += crbs; + last_pusch_alloc_slot = pusch_slot; } /// Determine if at least one bearer of the given UE is currently managed by this slice. @@ -66,6 +74,20 @@ class ran_slice_instance /// Returns UEs belonging to this slice. const slice_ue_repository& get_ues(); + /// Number of slots elapsed between the provided PDSCH slot and the last time this slice was scheduled. + unsigned nof_slots_since_last_pdsch(slot_point pdsch_slot) const + { + return last_pdsch_alloc_slot.valid() + ? (pdsch_slot >= last_pdsch_alloc_slot ? pdsch_slot - last_pdsch_alloc_slot : 0) + : MAX_SLOTS_SINCE_LAST_PXSCH; + } + unsigned nof_slots_since_last_pusch(slot_point pusch_slot) const + { + return last_pusch_alloc_slot.valid() + ? (pusch_slot >= last_pusch_alloc_slot ? pusch_slot - last_pusch_alloc_slot : 0) + : MAX_SLOTS_SINCE_LAST_PXSCH; + } + ran_slice_id_t id; const cell_configuration* cell_cfg; slice_rrm_policy_config cfg; @@ -82,6 +104,12 @@ class ran_slice_instance cell_cfg->tdd_cfg_common.has_value() ? nof_slots_per_tdd_period(*cell_cfg->tdd_cfg_common) : 1; private: + // Last slot that the PDSCH was allocated. + slot_point last_pdsch_alloc_slot; + + // Last slot that the PUSCH was allocated. + slot_point last_pusch_alloc_slot; + slice_ue_repository slice_ues; }; diff --git a/lib/scheduler/slicing/slice_scheduler.cpp b/lib/scheduler/slicing/slice_scheduler.cpp index c2b8d6dc30..d50545967e 100644 --- a/lib/scheduler/slicing/slice_scheduler.cpp +++ b/lib/scheduler/slicing/slice_scheduler.cpp @@ -246,6 +246,8 @@ template std::optional> slice_scheduler::get_next_candidate() { + using candidate_type = std::conditional_t; + slice_prio_queue& prio_queue = IsDownlink ? dl_prio_queue : ul_prio_queue; while (not prio_queue.empty()) { ran_slice_sched_context& chosen_slice = slices[prio_queue.top().id.value()]; @@ -276,13 +278,8 @@ slice_scheduler::get_next_candidate() prio_queue.push(slice_candidate_context{chosen_slice.inst.id, prio, {min_rbs, cfg.max_prb}, pxsch_slot}); } - // Save current slot count. - unsigned& count_to_set = IsDownlink ? chosen_slice.last_dl_slot : chosen_slice.last_ul_slot; - count_to_set = slot_count; - // Return the candidate. - return std::conditional_t{ - chosen_slice.inst, pxsch_slot, rb_lims.stop()}; + return candidate_type{chosen_slice.inst, pxsch_slot, rb_lims.stop()}; } return std::nullopt; } @@ -331,8 +328,9 @@ slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_pri not slice_resched and inst.cfg.min_prb > 0 and rb_count < inst.cfg.min_prb ? high_prio : default_prio; // Increase priorities of slices that have not been scheduled for a long time. - unsigned last_count = is_dl ? last_dl_slot : last_ul_slot; - priority_type delay_prio = (current_slot_count - last_count) & ((1U << delay_bitsize) - 1U); + priority_type delay_prio = + is_dl ? inst.nof_slots_since_last_pdsch(pxsch_slot) : inst.nof_slots_since_last_pusch(pxsch_slot); + delay_prio = delay_prio & ((1U << delay_bitsize) - 1U); // Round-robin across slices with the same slice and delay priorities. priority_type rr_prio = (current_slot_count % nof_slices) == inst.id.value() ? 1 : 0; diff --git a/lib/scheduler/slicing/slice_scheduler.h b/lib/scheduler/slicing/slice_scheduler.h index a71c251e6a..9542c94d48 100644 --- a/lib/scheduler/slicing/slice_scheduler.h +++ b/lib/scheduler/slicing/slice_scheduler.h @@ -56,9 +56,6 @@ class slice_scheduler struct ran_slice_sched_context { ran_slice_instance inst; std::unique_ptr policy; - // Counter tracking the last time this slice was scheduled as a candidate. - slot_count_type last_dl_slot = 0; - slot_count_type last_ul_slot = 0; ran_slice_sched_context(ran_slice_id_t id, const cell_configuration& cell_cfg, const slice_rrm_policy_config& cfg) : inst(id, cell_cfg, cfg) From e8ea5127c34a7eae31b76a1e4b49a1247d8527b8 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 26 Sep 2024 14:37:48 +0200 Subject: [PATCH 136/174] sched: fix scheduler slice priority computation, to prioritize earlier slots --- lib/scheduler/slicing/ran_slice_instance.cpp | 2 +- lib/scheduler/slicing/ran_slice_instance.h | 5 ++++ lib/scheduler/slicing/slice_scheduler.cpp | 27 ++++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/scheduler/slicing/ran_slice_instance.cpp b/lib/scheduler/slicing/ran_slice_instance.cpp index c644a9dd76..6135ed2486 100644 --- a/lib/scheduler/slicing/ran_slice_instance.cpp +++ b/lib/scheduler/slicing/ran_slice_instance.cpp @@ -33,7 +33,7 @@ void ran_slice_instance::slot_indication(slot_point slot_tx) pusch_rb_count_per_slot[(slot_tx - 1 - count).to_uint() % pusch_rb_count_per_slot.size()] = 0; } - // Reset last alloc slot if the different becomes to large, to avoid ambiguity. + // Reset last alloc slot if the difference becomes too large, to avoid ambiguity. if (last_pdsch_alloc_slot.valid() and slot_tx > last_pdsch_alloc_slot + MAX_SLOTS_SINCE_LAST_PXSCH) { last_pdsch_alloc_slot.clear(); } diff --git a/lib/scheduler/slicing/ran_slice_instance.h b/lib/scheduler/slicing/ran_slice_instance.h index 383b764ecb..0e1c92a742 100644 --- a/lib/scheduler/slicing/ran_slice_instance.h +++ b/lib/scheduler/slicing/ran_slice_instance.h @@ -74,6 +74,11 @@ class ran_slice_instance /// Returns UEs belonging to this slice. const slice_ue_repository& get_ues(); + unsigned nof_pusch_rbs_allocated(slot_point pusch_slot) const + { + return pusch_rb_count_per_slot[pusch_slot.to_uint() % pusch_rb_count_per_slot.size()]; + } + /// Number of slots elapsed between the provided PDSCH slot and the last time this slice was scheduled. unsigned nof_slots_since_last_pdsch(slot_point pdsch_slot) const { diff --git a/lib/scheduler/slicing/slice_scheduler.cpp b/lib/scheduler/slicing/slice_scheduler.cpp index d50545967e..7de1430f88 100644 --- a/lib/scheduler/slicing/slice_scheduler.cpp +++ b/lib/scheduler/slicing/slice_scheduler.cpp @@ -109,9 +109,9 @@ void slice_scheduler::slot_indication(slot_point slot_tx, const cell_resource_al // No more RBs left to allocated so skip adding slice candidate. continue; } - slot_point pusch_slot = slot_tx + pusch_time_domain_list[pusch_td_res_idx].k2; - unsigned pusch_rb_count = - slice.inst.pusch_rb_count_per_slot[pusch_slot.to_uint() % slice.inst.pusch_rb_count_per_slot.size()]; + + slot_point pusch_slot = slot_tx + pusch_time_domain_list[pusch_td_res_idx].k2; + unsigned pusch_rb_count = slice.inst.nof_pusch_rbs_allocated(pusch_slot); max_rbs = pusch_rb_count <= slice.inst.cfg.min_prb and slice.inst.cfg.min_prb > 0 ? slice.inst.cfg.min_prb : slice.inst.cfg.max_prb; ul_prio_queue.push( @@ -312,17 +312,20 @@ slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_pri // Priority when slice has already reached its minimum RB ratio agreement. static constexpr priority_type default_prio = 0x1U; // Priority when slice still needs to reach its minimum RB ratio agreement. - static constexpr priority_type high_prio = 0x2U; - static constexpr priority_type delay_bitsize = 8U; - static constexpr priority_type rr_bitsize = 8U; + static constexpr priority_type high_prio = 0x2U; + static constexpr priority_type slice_prio_bitsize = 4U; + static constexpr priority_type delay_bitsize = 8U; + static constexpr priority_type rr_bitsize = 8U; - unsigned rb_count = is_dl ? inst.pdsch_rb_count - : inst.pusch_rb_count_per_slot[pxsch_slot.to_uint() % inst.pusch_rb_count_per_slot.size()]; + unsigned rb_count = is_dl ? inst.pdsch_rb_count : inst.nof_pusch_rbs_allocated(pxsch_slot); if (not inst.active() or rb_count >= inst.cfg.max_prb) { // If the slice is not in a state to be scheduled in this slot, return skip priority level. return skip_prio; } + // Prioritize closer slots over slots further away into the future. This is relevant for UL-heavy cases. + unsigned slot_dist = 0xfU - ((pxsch_slot - pdcch_slot) & 0xfU); + // In case minRB > 0 and minimum RB ratio agreement is not yet reached, we give it a higher priority. priority_type slice_prio = not slice_resched and inst.cfg.min_prb > 0 and rb_count < inst.cfg.min_prb ? high_prio : default_prio; @@ -336,10 +339,6 @@ slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_pri priority_type rr_prio = (current_slot_count % nof_slices) == inst.id.value() ? 1 : 0; rr_prio = rr_prio & ((1U << rr_bitsize) - 1U); - // Give higher priority to slice with PxSCH slot closer to PDCCH slot. This is done to ensure that PxSCH does not get - // allocated too far in future such that no PxSCH can be allocated in the slots between current PDCCH slot and the - // slot at which PxSCH is allocated. - unsigned slot_diff = pxsch_slot - pdcch_slot; - - return (slice_prio << (delay_bitsize + rr_bitsize)) + (delay_prio << rr_bitsize) + rr_prio - slot_diff; + return (slot_dist << (delay_bitsize + rr_bitsize + slice_prio_bitsize)) + + (slice_prio << (delay_bitsize + rr_bitsize)) + (delay_prio << rr_bitsize) + rr_prio; } From 5030a4c343d3b6950746b4f7d8b87efcdbbaac27 Mon Sep 17 00:00:00 2001 From: Robert Falkenberg Date: Wed, 25 Sep 2024 10:30:44 +0200 Subject: [PATCH 137/174] nru,du: handle polling of delivery status report --- lib/f1u/du/f1u_bearer_impl.cpp | 26 +++- lib/f1u/du/f1u_bearer_impl.h | 1 + tests/unittests/f1u/du/f1u_du_bearer_test.cpp | 126 ++++++++++++++++++ 3 files changed, 149 insertions(+), 4 deletions(-) diff --git a/lib/f1u/du/f1u_bearer_impl.cpp b/lib/f1u/du/f1u_bearer_impl.cpp index 515e306113..05c0eae427 100644 --- a/lib/f1u/du/f1u_bearer_impl.cpp +++ b/lib/f1u/du/f1u_bearer_impl.cpp @@ -81,6 +81,14 @@ void f1u_bearer_impl::handle_pdu_impl(nru_dl_message msg) logger.log_debug("Delivering T-PDU. size={}", msg.t_pdu.length()); rx_sdu_notifier.on_new_sdu(std::move(msg.t_pdu), msg.dl_user_data.retransmission_flag); } + // handle polling of delivery status report + if (msg.dl_user_data.report_polling) { + if (send_data_delivery_status()) { + logger.log_debug("Report polling flag is set. Sent data delivery status"); + } else { + logger.log_warning("Report polling flag is set. No data to be sent in data delivery status"); + } + } // handle discard notifications if (msg.dl_user_data.discard_blocks.has_value()) { nru_pdcp_sn_discard_blocks& blocks = msg.dl_user_data.discard_blocks.value(); @@ -224,12 +232,22 @@ void f1u_bearer_impl::fill_data_delivery_status(nru_ul_message& msg) ul_notif_timer.run(); } -void f1u_bearer_impl::on_expired_ul_notif_timer() +bool f1u_bearer_impl::send_data_delivery_status() { nru_ul_message msg = {}; fill_data_delivery_status(msg); - if (msg.data_delivery_status.has_value()) { - logger.log_debug("Sending data delivery status due to expired UL notification timer"); - tx_pdu_notifier.on_new_pdu(std::move(msg)); + if (!msg.data_delivery_status.has_value()) { + return false; + } + tx_pdu_notifier.on_new_pdu(std::move(msg)); + return true; +} + +void f1u_bearer_impl::on_expired_ul_notif_timer() +{ + if (send_data_delivery_status()) { + logger.log_debug("UL notification timer expired. Sent data delivery status"); + } else { + logger.log_debug("UL notification timer expired. No data to be sent in data delivery status"); } } diff --git a/lib/f1u/du/f1u_bearer_impl.h b/lib/f1u/du/f1u_bearer_impl.h index 13e306edd6..0683fe0890 100644 --- a/lib/f1u/du/f1u_bearer_impl.h +++ b/lib/f1u/du/f1u_bearer_impl.h @@ -99,6 +99,7 @@ class f1u_bearer_impl final : public f1u_bearer, bool fill_highest_retransmitted_pdcp_sn(nru_dl_data_delivery_status& status); bool fill_highest_delivered_retransmitted_pdcp_sn(nru_dl_data_delivery_status& status); void fill_data_delivery_status(nru_ul_message& msg); + bool send_data_delivery_status(); void handle_pdu_impl(nru_dl_message msg); diff --git a/tests/unittests/f1u/du/f1u_du_bearer_test.cpp b/tests/unittests/f1u/du/f1u_du_bearer_test.cpp index 5a209729b3..42af1fce70 100644 --- a/tests/unittests/f1u/du/f1u_du_bearer_test.cpp +++ b/tests/unittests/f1u/du/f1u_du_bearer_test.cpp @@ -473,3 +473,129 @@ TEST_F(f1u_du_test, tx_delivery_notification) EXPECT_TRUE(tester->tx_msg_list.empty()); } + +TEST_F(f1u_du_test, rx_with_poll_triggers_ddds_when_transmit_was_notified) +{ + constexpr uint32_t highest_pdcp_sn = 123; + + // Notify transmit + f1u->handle_transmit_notification(highest_pdcp_sn, 0); + f1u->handle_transmit_notification(highest_pdcp_sn + 1, 0); + + EXPECT_TRUE(tester->rx_discard_sdu_list.empty()); + EXPECT_TRUE(tester->rx_sdu_list.empty()); + + // DL message with poll for DL Data Delivery Status Report + constexpr uint32_t pdu_size = 10; + byte_buffer rx_pdcp_pdu1 = create_sdu_byte_buffer(pdu_size, 0); + nru_dl_message msg1 = {}; + msg1.t_pdu = rx_pdcp_pdu1.deep_copy().value(); + msg1.dl_user_data.report_polling = true; + f1u->handle_pdu(std::move(msg1)); + + // This should immediately trigger a DDDS + ASSERT_FALSE(tester->tx_msg_list.empty()); + EXPECT_FALSE(tester->tx_msg_list.front().t_pdu.has_value()); + EXPECT_FALSE(tester->tx_msg_list.front().assistance_information.has_value()); + ASSERT_TRUE(tester->tx_msg_list.front().data_delivery_status.has_value()); + { + nru_dl_data_delivery_status& status = tester->tx_msg_list.front().data_delivery_status.value(); + EXPECT_FALSE(status.final_frame_ind); + EXPECT_FALSE(status.lost_nru_sn_ranges.has_value()); + EXPECT_FALSE(status.highest_delivered_pdcp_sn.has_value()); + EXPECT_FALSE(status.cause_value.has_value()); + EXPECT_FALSE(status.highest_delivered_retransmitted_pdcp_sn.has_value()); + EXPECT_FALSE(status.highest_retransmitted_pdcp_sn.has_value()); + ASSERT_TRUE(status.highest_transmitted_pdcp_sn.has_value()); + EXPECT_EQ(status.highest_transmitted_pdcp_sn.value(), highest_pdcp_sn + 1); + } + tester->tx_msg_list.pop_front(); + + EXPECT_TRUE(tester->tx_msg_list.empty()); + + // Also check that the DL PDU was properly forwarded + ASSERT_FALSE(tester->rx_sdu_list.empty()); + EXPECT_EQ(tester->rx_sdu_list.front().first, rx_pdcp_pdu1); + EXPECT_FALSE(tester->rx_sdu_list.front().second); + + tester->rx_sdu_list.pop_front(); + + EXPECT_TRUE(tester->rx_sdu_list.empty()); +} + +TEST_F(f1u_du_test, rx_with_poll_triggers_ddds_when_delivery_was_notified) +{ + constexpr uint32_t highest_pdcp_sn = 123; + + // Notify delivery + f1u->handle_delivery_notification(highest_pdcp_sn); + f1u->handle_delivery_notification(highest_pdcp_sn + 1); + + EXPECT_TRUE(tester->rx_discard_sdu_list.empty()); + EXPECT_TRUE(tester->rx_sdu_list.empty()); + + // DL message with poll for DL Data Delivery Status Report + constexpr uint32_t pdu_size = 10; + byte_buffer rx_pdcp_pdu1 = create_sdu_byte_buffer(pdu_size, 0); + nru_dl_message msg1 = {}; + msg1.t_pdu = rx_pdcp_pdu1.deep_copy().value(); + msg1.dl_user_data.report_polling = true; + f1u->handle_pdu(std::move(msg1)); + + // This should immediately trigger a DDDS + ASSERT_FALSE(tester->tx_msg_list.empty()); + EXPECT_FALSE(tester->tx_msg_list.front().t_pdu.has_value()); + EXPECT_FALSE(tester->tx_msg_list.front().assistance_information.has_value()); + ASSERT_TRUE(tester->tx_msg_list.front().data_delivery_status.has_value()); + { + nru_dl_data_delivery_status& status = tester->tx_msg_list.front().data_delivery_status.value(); + EXPECT_FALSE(status.final_frame_ind); + EXPECT_FALSE(status.lost_nru_sn_ranges.has_value()); + EXPECT_FALSE(status.highest_transmitted_pdcp_sn.has_value()); + EXPECT_FALSE(status.cause_value.has_value()); + EXPECT_FALSE(status.highest_delivered_retransmitted_pdcp_sn.has_value()); + EXPECT_FALSE(status.highest_retransmitted_pdcp_sn.has_value()); + ASSERT_TRUE(status.highest_delivered_pdcp_sn.has_value()); + EXPECT_EQ(status.highest_delivered_pdcp_sn.value(), highest_pdcp_sn + 1); + } + tester->tx_msg_list.pop_front(); + + EXPECT_TRUE(tester->tx_msg_list.empty()); + + // Also check that the DL PDU was properly forwarded + ASSERT_FALSE(tester->rx_sdu_list.empty()); + EXPECT_EQ(tester->rx_sdu_list.front().first, rx_pdcp_pdu1); + EXPECT_FALSE(tester->rx_sdu_list.front().second); + + tester->rx_sdu_list.pop_front(); + + EXPECT_TRUE(tester->rx_sdu_list.empty()); +} + +TEST_F(f1u_du_test, rx_with_poll_triggers_no_ddds_when_nothing_was_notified) +{ + // Do not notify any transmit or delivery + + EXPECT_TRUE(tester->rx_discard_sdu_list.empty()); + EXPECT_TRUE(tester->rx_sdu_list.empty()); + + // DL message with poll for DL Data Delivery Status Report + constexpr uint32_t pdu_size = 10; + byte_buffer rx_pdcp_pdu1 = create_sdu_byte_buffer(pdu_size, 0); + nru_dl_message msg1 = {}; + msg1.t_pdu = rx_pdcp_pdu1.deep_copy().value(); + msg1.dl_user_data.report_polling = true; + f1u->handle_pdu(std::move(msg1)); + + // This should not trigger a DDDS, because no data is available yet + EXPECT_TRUE(tester->tx_msg_list.empty()); + + // Also check that the DL PDU was properly forwarded + ASSERT_FALSE(tester->rx_sdu_list.empty()); + EXPECT_EQ(tester->rx_sdu_list.front().first, rx_pdcp_pdu1); + EXPECT_FALSE(tester->rx_sdu_list.front().second); + + tester->rx_sdu_list.pop_front(); + + EXPECT_TRUE(tester->rx_sdu_list.empty()); +} From ca7f9d878e4a6adeed1f146458bc5e8b95c875d5 Mon Sep 17 00:00:00 2001 From: Robert Falkenberg Date: Thu, 26 Sep 2024 14:11:33 +0200 Subject: [PATCH 138/174] nru,du: cosmetic rename of flag wheter DDDS value was added or not --- lib/f1u/du/f1u_bearer_impl.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/f1u/du/f1u_bearer_impl.cpp b/lib/f1u/du/f1u_bearer_impl.cpp index 05c0eae427..39e0e2821f 100644 --- a/lib/f1u/du/f1u_bearer_impl.cpp +++ b/lib/f1u/du/f1u_bearer_impl.cpp @@ -214,16 +214,16 @@ bool f1u_bearer_impl::fill_highest_delivered_retransmitted_pdcp_sn(nru_dl_data_d void f1u_bearer_impl::fill_data_delivery_status(nru_ul_message& msg) { - nru_dl_data_delivery_status status = {}; - bool status_changed = false; + nru_dl_data_delivery_status status = {}; + bool value_added = false; - status_changed |= fill_desired_buffer_size_of_data_radio_bearer(status); - status_changed |= fill_highest_transmitted_pdcp_sn(status); - status_changed |= fill_highest_delivered_pdcp_sn(status); - status_changed |= fill_highest_retransmitted_pdcp_sn(status); - status_changed |= fill_highest_delivered_retransmitted_pdcp_sn(status); + value_added |= fill_desired_buffer_size_of_data_radio_bearer(status); + value_added |= fill_highest_transmitted_pdcp_sn(status); + value_added |= fill_highest_delivered_pdcp_sn(status); + value_added |= fill_highest_retransmitted_pdcp_sn(status); + value_added |= fill_highest_delivered_retransmitted_pdcp_sn(status); - if (status_changed) { + if (value_added) { logger.log_debug("Adding data delivery status to NR-U message"); msg.data_delivery_status = std::move(status); } From c62e50dda71245346e7140d51fe80c073e653b59 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 26 Sep 2024 12:58:34 +0200 Subject: [PATCH 139/174] sched: small cleanups in the ue_scheduler --- .../ue_scheduling/ue_scheduler_impl.cpp | 55 ++++++++++--------- .../ue_scheduling/ue_scheduler_impl.h | 7 ++- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp index 2ad943cc6e..22b5433695 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp @@ -28,13 +28,13 @@ ue_scheduler_impl::ue_scheduler_impl(const scheduler_ue_expert_config& expert_cf void ue_scheduler_impl::add_cell(const ue_scheduler_cell_params& params) { ue_res_grid_view.add_cell(*params.cell_res_alloc); - cells[params.cell_index] = std::make_unique(expert_cfg, params, ue_db, metrics_handler); + cells.emplace(params.cell_index, expert_cfg, params, ue_db, metrics_handler); event_mng.add_cell(*params.cell_res_alloc, - cells[params.cell_index]->cell_harqs, - cells[params.cell_index]->fallback_sched, - cells[params.cell_index]->uci_sched, + cells[params.cell_index].cell_harqs, + cells[params.cell_index].fallback_sched, + cells[params.cell_index].uci_sched, *params.ev_logger, - cells[params.cell_index]->slice_sched); + cells[params.cell_index].slice_sched); ue_alloc.add_cell(params.cell_index, *params.pdcch_sched, *params.uci_alloc, *params.cell_res_alloc); } @@ -51,31 +51,31 @@ void ue_scheduler_impl::run_sched_strategy(slot_point slot_tx, du_cell_index_t c } // Update slice context and compute slice priorities. - cells[cell_index]->slice_sched.slot_indication(slot_tx, ue_res_grid_view.get_grid(cell_index)); + cells[cell_index].slice_sched.slot_indication(slot_tx, ue_res_grid_view.get_grid(cell_index)); // Perform round-robin prioritization of UL and DL scheduling. This gives unfair preference to DL over UL. This is // done to avoid the issue of sending wrong DAI value in DCI format 0_1 to UE while the PDSCH is allocated // right after allocating PUSCH in the same slot, resulting in gNB expecting 1 HARQ ACK bit to be multiplexed in // UCI in PUSCH and UE sending 4 HARQ ACK bits (DAI = 3). // Example: K1==K2=4 and PUSCH is allocated before PDSCH. - if (expert_cfg.enable_csi_rs_pdsch_multiplexing or (*cells[cell_index]->cell_res_alloc)[0].result.dl.csi_rs.empty()) { - auto dl_slice_candidate = cells[cell_index]->slice_sched.get_next_dl_candidate(); + if (expert_cfg.enable_csi_rs_pdsch_multiplexing or (*cells[cell_index].cell_res_alloc)[0].result.dl.csi_rs.empty()) { + auto dl_slice_candidate = cells[cell_index].slice_sched.get_next_dl_candidate(); while (dl_slice_candidate.has_value()) { - auto& policy = cells[cell_index]->slice_sched.get_policy(dl_slice_candidate->id()); + auto& policy = cells[cell_index].slice_sched.get_policy(dl_slice_candidate->id()); dl_slice_ue_cell_grid_allocator slice_pdsch_alloc{ue_alloc, *dl_slice_candidate}; policy.dl_sched( - slice_pdsch_alloc, ue_res_grid_view, *dl_slice_candidate, cells[cell_index]->cell_harqs.pending_dl_retxs()); - dl_slice_candidate = cells[cell_index]->slice_sched.get_next_dl_candidate(); + slice_pdsch_alloc, ue_res_grid_view, *dl_slice_candidate, cells[cell_index].cell_harqs.pending_dl_retxs()); + dl_slice_candidate = cells[cell_index].slice_sched.get_next_dl_candidate(); } } - auto ul_slice_candidate = cells[cell_index]->slice_sched.get_next_ul_candidate(); + auto ul_slice_candidate = cells[cell_index].slice_sched.get_next_ul_candidate(); while (ul_slice_candidate.has_value()) { - auto& policy = cells[cell_index]->slice_sched.get_policy(ul_slice_candidate->id()); + auto& policy = cells[cell_index].slice_sched.get_policy(ul_slice_candidate->id()); ul_slice_ue_cell_grid_allocator slice_pusch_alloc{ue_alloc, *ul_slice_candidate}; policy.ul_sched( - slice_pusch_alloc, ue_res_grid_view, *ul_slice_candidate, cells[cell_index]->cell_harqs.pending_ul_retxs()); - ul_slice_candidate = cells[cell_index]->slice_sched.get_next_ul_candidate(); + slice_pusch_alloc, ue_res_grid_view, *ul_slice_candidate, cells[cell_index].cell_harqs.pending_ul_retxs()); + ul_slice_candidate = cells[cell_index].slice_sched.get_next_ul_candidate(); } } @@ -178,30 +178,35 @@ void ue_scheduler_impl::puxch_grant_sanitizer(cell_resource_allocator& cell_allo void ue_scheduler_impl::run_slot(slot_point slot_tx, du_cell_index_t cell_index) { + std::unique_lock lock(cell_group_mutex, std::defer_lock); + if (cells.size() > 1) { + // Only mutex if the cell group has more than one cell (Carrier Aggregation case). + lock.lock(); + } + // Process any pending events that are directed at UEs. event_mng.run(slot_tx, cell_index); // Mark the start of a new slot in the UE grid allocator. ue_alloc.slot_indication(slot_tx); + // Check for timeouts in the cell HARQ processes. + cells[cell_index].cell_harqs.slot_indication(slot_tx); + // Schedule periodic UCI (SR and CSI) before any UL grants. - cells[cell_index]->uci_sched.run_slot(*cells[cell_index]->cell_res_alloc); + cells[cell_index].uci_sched.run_slot(*cells[cell_index].cell_res_alloc); // Run cell-specific SRB0 scheduler. - cells[cell_index]->fallback_sched.run_slot(*cells[cell_index]->cell_res_alloc); - - // Check for timeouts in the cell HARQ processes. - cells[cell_index]->cell_harqs.slot_indication(slot_tx); + cells[cell_index].fallback_sched.run_slot(*cells[cell_index].cell_res_alloc); - // Synchronize all carriers. Last thread to reach this synchronization point, runs UE scheduling strategy. - sync_point.wait( - slot_tx, ue_alloc.nof_cells(), [this, slot_tx, cell_index]() { run_sched_strategy(slot_tx, cell_index); }); + // Run slice scheduler policies. + run_sched_strategy(slot_tx, cell_index); // Update the PUCCH counter after the UE DL and UL scheduler. - update_harq_pucch_counter(*cells[cell_index]->cell_res_alloc); + update_harq_pucch_counter(*cells[cell_index].cell_res_alloc); // TODO: remove this. - puxch_grant_sanitizer(*cells[cell_index]->cell_res_alloc); + puxch_grant_sanitizer(*cells[cell_index].cell_res_alloc); } namespace { diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.h b/lib/scheduler/ue_scheduling/ue_scheduler_impl.h index 9e4efbef53..1803af6dd1 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.h +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.h @@ -87,7 +87,8 @@ class ue_scheduler_impl final : public ue_scheduler const scheduler_ue_expert_config& expert_cfg; cell_metrics_handler& metrics_handler; - std::array, MAX_NOF_DU_CELLS> cells; + // List of cells of the UE scheduler. + slotted_array cells; /// Scheduling Strategy. ue_resource_grid_view ue_res_grid_view; @@ -101,8 +102,8 @@ class ue_scheduler_impl final : public ue_scheduler /// Processor of UE input events. ue_event_manager event_mng; - /// Mutex used to lock carriers for joint carrier scheduling. - slot_sync_point sync_point; + // Mutex to lock cells of the same cell group (when CA enabled) for joint carrier scheduling + std::mutex cell_group_mutex; srslog::basic_logger& logger; }; From d4ba855317001dc9b84e3f3e29e1b33b97cd420f Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 26 Sep 2024 15:05:36 +0200 Subject: [PATCH 140/174] sched: fix ue_scheduler run of more than one cell per cell group --- lib/scheduler/cell_scheduler.cpp | 2 +- lib/scheduler/ue_scheduling/ue_scheduler.h | 2 +- .../ue_scheduling/ue_scheduler_impl.cpp | 43 +++++++++++-------- .../ue_scheduling/ue_scheduler_impl.h | 6 ++- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/lib/scheduler/cell_scheduler.cpp b/lib/scheduler/cell_scheduler.cpp index 8d2e3efc5f..e9d82df425 100644 --- a/lib/scheduler/cell_scheduler.cpp +++ b/lib/scheduler/cell_scheduler.cpp @@ -116,7 +116,7 @@ void cell_scheduler::run_slot(slot_point sl_tx) pg_sch.schedule_paging(res_grid); // > Schedule UE DL and UL data. - ue_sched.run_slot(sl_tx, cell_cfg.cell_index); + ue_sched.run_slot(sl_tx); // > Mark stop of the slot processing auto slot_stop_tp = std::chrono::high_resolution_clock::now(); diff --git a/lib/scheduler/ue_scheduling/ue_scheduler.h b/lib/scheduler/ue_scheduling/ue_scheduler.h index 6f5aa40b11..c2b1c40e68 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler.h +++ b/lib/scheduler/ue_scheduling/ue_scheduler.h @@ -40,7 +40,7 @@ class ue_scheduler virtual void add_cell(const ue_scheduler_cell_params& params) = 0; /// Schedule UE DL and UL grants for a given {slot, cell}. - virtual void run_slot(slot_point slot_tx, du_cell_index_t cell_index) = 0; + virtual void run_slot(slot_point slot_tx) = 0; /// Handle error in the lower layers. virtual void handle_error_indication(slot_point sl_tx, diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp index 22b5433695..6120eee1e5 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp @@ -176,37 +176,46 @@ void ue_scheduler_impl::puxch_grant_sanitizer(cell_resource_allocator& cell_allo } } -void ue_scheduler_impl::run_slot(slot_point slot_tx, du_cell_index_t cell_index) +void ue_scheduler_impl::run_slot(slot_point slot_tx) { std::unique_lock lock(cell_group_mutex, std::defer_lock); if (cells.size() > 1) { // Only mutex if the cell group has more than one cell (Carrier Aggregation case). lock.lock(); } + if (last_sl_ind == slot_tx) { + // This slot has already been processed by a cell of the same cell group. + return; + } + last_sl_ind = slot_tx; - // Process any pending events that are directed at UEs. - event_mng.run(slot_tx, cell_index); + for (auto& group_cell : cells) { + du_cell_index_t cell_index = group_cell.cell_res_alloc->cfg.cell_index; - // Mark the start of a new slot in the UE grid allocator. - ue_alloc.slot_indication(slot_tx); + // Process any pending events that are directed at UEs. + event_mng.run(slot_tx, cell_index); - // Check for timeouts in the cell HARQ processes. - cells[cell_index].cell_harqs.slot_indication(slot_tx); + // Mark the start of a new slot in the UE grid allocator. + ue_alloc.slot_indication(slot_tx); - // Schedule periodic UCI (SR and CSI) before any UL grants. - cells[cell_index].uci_sched.run_slot(*cells[cell_index].cell_res_alloc); + // Check for timeouts in the cell HARQ processes. + group_cell.cell_harqs.slot_indication(slot_tx); - // Run cell-specific SRB0 scheduler. - cells[cell_index].fallback_sched.run_slot(*cells[cell_index].cell_res_alloc); + // Schedule periodic UCI (SR and CSI) before any UL grants. + group_cell.uci_sched.run_slot(*group_cell.cell_res_alloc); - // Run slice scheduler policies. - run_sched_strategy(slot_tx, cell_index); + // Run cell-specific SRB0 scheduler. + group_cell.fallback_sched.run_slot(*group_cell.cell_res_alloc); - // Update the PUCCH counter after the UE DL and UL scheduler. - update_harq_pucch_counter(*cells[cell_index].cell_res_alloc); + // Run slice scheduler policies. + run_sched_strategy(slot_tx, cell_index); - // TODO: remove this. - puxch_grant_sanitizer(*cells[cell_index].cell_res_alloc); + // Update the PUCCH counter after the UE DL and UL scheduler. + update_harq_pucch_counter(*group_cell.cell_res_alloc); + + // TODO: remove this. + puxch_grant_sanitizer(*group_cell.cell_res_alloc); + } } namespace { diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.h b/lib/scheduler/ue_scheduling/ue_scheduler_impl.h index 1803af6dd1..b4c4715167 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.h +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.h @@ -15,7 +15,6 @@ #include "../policy/scheduler_policy.h" #include "../pucch_scheduling/pucch_guardbands_scheduler.h" #include "../slicing/slice_scheduler.h" -#include "../support/slot_sync_point.h" #include "../uci_scheduling/uci_scheduler_impl.h" #include "ue_cell_grid_allocator.h" #include "ue_event_manager.h" @@ -38,7 +37,7 @@ class ue_scheduler_impl final : public ue_scheduler void add_cell(const ue_scheduler_cell_params& params) override; /// Schedule UE DL grants for a given {slot, cell}. - void run_slot(slot_point slot_tx, du_cell_index_t cell_index) override; + void run_slot(slot_point slot_tx) override; void handle_error_indication(slot_point sl_tx, du_cell_index_t cell_index, @@ -105,6 +104,9 @@ class ue_scheduler_impl final : public ue_scheduler // Mutex to lock cells of the same cell group (when CA enabled) for joint carrier scheduling std::mutex cell_group_mutex; + // Last slot run. + slot_point last_sl_ind; + srslog::basic_logger& logger; }; From 81cccd1bc418f474ea7570b2c98148a9307863cd Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 24 Sep 2024 17:55:13 +0200 Subject: [PATCH 141/174] cu_cp: add admission control for maximum number of drbs per ue --- apps/units/cu_cp/cu_cp_config_translators.cpp | 1 + apps/units/cu_cp/cu_cp_unit_config.h | 6 +++-- .../cu_cp/cu_cp_unit_config_cli11_schema.cpp | 4 ++++ .../cu_cp/cu_cp_unit_config_yaml_writer.cpp | 1 + include/srsran/cu_cp/cu_cp_configuration.h | 2 ++ include/srsran/cu_cp/up_context.h | 1 + lib/cu_cp/ue_manager/ue_manager_impl.cpp | 2 +- .../up_resource_manager_helpers.cpp | 23 +++++++++++++++---- .../up_resource_manager_helpers.h | 1 + ...cu_cp_pdu_session_resource_modify_test.cpp | 9 +++++--- .../cu_cp/cu_cp_test_environment.cpp | 15 ++++++------ .../unittests/cu_cp/cu_cp_test_environment.h | 9 +++++--- .../up_resource_manager_test.cpp | 2 +- 13 files changed, 54 insertions(+), 22 deletions(-) diff --git a/apps/units/cu_cp/cu_cp_config_translators.cpp b/apps/units/cu_cp/cu_cp_config_translators.cpp index 0d830a5376..93dec3b157 100644 --- a/apps/units/cu_cp/cu_cp_config_translators.cpp +++ b/apps/units/cu_cp/cu_cp_config_translators.cpp @@ -325,6 +325,7 @@ srs_cu_cp::cu_cp_configuration srsran::generate_cu_cp_config(const cu_cp_unit_co out_cfg.admission.max_nof_dus = cu_cfg.max_nof_dus; out_cfg.admission.max_nof_cu_ups = cu_cfg.max_nof_cu_ups; out_cfg.admission.max_nof_ues = cu_cfg.max_nof_ues; + out_cfg.admission.max_nof_drbs_per_ue = cu_cfg.max_nof_drbs_per_ue; out_cfg.node.gnb_id = cu_cfg.gnb_id; out_cfg.node.ran_node_name = cu_cfg.ran_node_name; diff --git a/apps/units/cu_cp/cu_cp_unit_config.h b/apps/units/cu_cp/cu_cp_unit_config.h index 7eb604af86..8d2b924707 100644 --- a/apps/units/cu_cp/cu_cp_unit_config.h +++ b/apps/units/cu_cp/cu_cp_unit_config.h @@ -260,8 +260,12 @@ struct cu_cp_unit_config { uint16_t max_nof_cu_ups = 6; /// Maximum number of UEs. uint64_t max_nof_ues = 8192; + /// Maximum number of DRBs per UE. + uint8_t max_nof_drbs_per_ue = 8; /// Inactivity timer in seconds. int inactivity_timer = 120; + /// PDU session setup timeout in seconds (must be larger than T310). + unsigned pdu_session_setup_timeout = 3; /// Load enterprise plugins. bool load_plugins = false; /// Function pointer to start NG handover from plugin @@ -270,8 +274,6 @@ struct cu_cp_unit_config { void* connect_amfs_func_ptr; /// Function pointer to disconnect from AMFs from plugin void* disconnect_amfs_func_ptr; - /// PDU session setup timeout in seconds (must be larger than T310). - unsigned pdu_session_setup_timeout = 3; /// Loggers configuration. cu_cp_unit_logger_config loggers; /// PCAPs configuration. diff --git a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp index 09727f86ca..2a79ad072e 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp +++ b/apps/units/cu_cp/cu_cp_unit_config_cli11_schema.cpp @@ -363,6 +363,10 @@ static void configure_cli11_cu_cp_args(CLI::App& app, cu_cp_unit_config& cu_cp_p add_option(app, "--max_nof_ues", cu_cp_params.max_nof_ues, "Maximum number of UEs that the CU-CP may accept"); + add_option(app, "--max_nof_drbs_per_ue", cu_cp_params.max_nof_drbs_per_ue, "Maximum number of DRBs per UE") + ->capture_default_str() + ->check(CLI::Range(1, 29)); + add_option(app, "--inactivity_timer", cu_cp_params.inactivity_timer, "UE/PDU Session/DRB inactivity timer in seconds") ->capture_default_str() ->check(CLI::Range(1, 7200)); diff --git a/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp b/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp index 9812a65d5d..c251e75f64 100644 --- a/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp +++ b/apps/units/cu_cp/cu_cp_unit_config_yaml_writer.cpp @@ -231,6 +231,7 @@ static YAML::Node build_cu_cp_section(const cu_cp_unit_config& config) node["max_nof_dus"] = config.max_nof_dus; node["max_nof_cu_ups"] = config.max_nof_cu_ups; node["max_nof_ues"] = config.max_nof_ues; + node["max_nof_drbs_per_ue"] = config.max_nof_drbs_per_ue; node["inactivity_timer"] = config.inactivity_timer; node["pdu_session_setup_timeout"] = config.pdu_session_setup_timeout; diff --git a/include/srsran/cu_cp/cu_cp_configuration.h b/include/srsran/cu_cp/cu_cp_configuration.h index 2f69b2ece7..bb2ed5cf44 100644 --- a/include/srsran/cu_cp/cu_cp_configuration.h +++ b/include/srsran/cu_cp/cu_cp_configuration.h @@ -62,6 +62,8 @@ struct cu_cp_configuration { unsigned max_nof_cu_ups = 6; /// Maximum number of UEs that the CU-CP may accept. unsigned max_nof_ues = 8192; + /// Maximum number of DRBs per UE that the CU-CP will configure. + uint8_t max_nof_drbs_per_ue = 8; }; struct service_params { task_executor* cu_cp_executor = nullptr; diff --git a/include/srsran/cu_cp/up_context.h b/include/srsran/cu_cp/up_context.h index 7a31f5ff75..ad8748aaee 100644 --- a/include/srsran/cu_cp/up_context.h +++ b/include/srsran/cu_cp/up_context.h @@ -21,6 +21,7 @@ namespace srs_cu_cp { /// \brief List of all supported 5QIs and their corresponding PDCP/SDAP configs struct up_resource_manager_cfg { std::map five_qi_config; ///< Configuration for available 5QI. + uint8_t max_nof_drbs_per_ue; }; struct up_qos_flow_context { diff --git a/lib/cu_cp/ue_manager/ue_manager_impl.cpp b/lib/cu_cp/ue_manager/ue_manager_impl.cpp index 29b79bf3c0..95bc054a4c 100644 --- a/lib/cu_cp/ue_manager/ue_manager_impl.cpp +++ b/lib/cu_cp/ue_manager/ue_manager_impl.cpp @@ -21,7 +21,7 @@ void cu_cp_ue::stop() ue_manager::ue_manager(const cu_cp_configuration& cu_cp_cfg) : ue_config(cu_cp_cfg.ue), - up_config(up_resource_manager_cfg{cu_cp_cfg.bearers.drb_config}), + up_config(up_resource_manager_cfg{cu_cp_cfg.bearers.drb_config, cu_cp_cfg.admission.max_nof_drbs_per_ue}), sec_config(security_manager_config{cu_cp_cfg.security.int_algo_pref_list, cu_cp_cfg.security.enc_algo_pref_list}), max_nof_ues(cu_cp_cfg.admission.max_nof_ues), ue_task_scheds(*cu_cp_cfg.services.timers, *cu_cp_cfg.services.cu_cp_executor, logger) diff --git a/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.cpp b/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.cpp index a401b03a3b..f6b3f74e52 100644 --- a/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.cpp +++ b/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.cpp @@ -52,10 +52,13 @@ bool contains_drb(const up_pdu_session_context_update& new_session_context, drb_ drb_id_t srsran::srs_cu_cp::allocate_drb_id(const up_pdu_session_context_update& new_session_context, const up_context& context, const up_config_update& config_update, + uint8_t max_nof_drbs_per_ue, const srslog::basic_logger& logger) { - if (context.drb_map.size() >= MAX_NOF_DRBS) { - logger.warning("No more DRBs available"); + if (context.drb_map.size() >= max_nof_drbs_per_ue) { + logger.warning("DRB creation failed. Cause: Maximum number of DRBs per UE already created ({}). To increase the " + "number of allowed DRBs per UE change the \"--max_nof_drbs_per_ue\" in the CU-CP configuration\n", + max_nof_drbs_per_ue); return drb_id_t::invalid; } @@ -65,8 +68,11 @@ drb_id_t srsran::srs_cu_cp::allocate_drb_id(const up_pdu_session_context_update& contains_drb(new_session_context, new_drb_id)) { /// try next new_drb_id = uint_to_drb_id(drb_id_to_uint(new_drb_id) + 1); - if (new_drb_id == drb_id_t::invalid) { - logger.warning("No more DRBs available"); + + if (drb_id_to_uint(new_drb_id) > max_nof_drbs_per_ue) { + logger.warning("DRB creation failed. Cause: Maximum number of DRBs per UE already created ({}). To increase the " + "number of allowed DRBs per UE change the \"--max_nof_drbs_per_ue\" in the CU-CP configuration\n", + max_nof_drbs_per_ue); return drb_id_t::invalid; } } @@ -209,7 +215,14 @@ drb_id_t allocate_qos_flow(up_pdu_session_context_update& new_session_contex // Note: We map QoS flows to DRBs in a 1:1 manner meaning that each flow gets it's own DRB. // potential optimization to support more QoS flows is to map non-GPB flows onto existing DRBs. - drb_id_t drb_id = allocate_drb_id(new_session_context, full_context, config_update, logger); + if (full_context.drb_map.size() >= cfg.max_nof_drbs_per_ue) { + logger.warning("DRB creation failed. Cause: Maximum number of DRBs per UE already created ({}). To increase the " + "number of allowed DRBs per UE change the \"--max_nof_drbs_per_ue\" in the CU-CP configuration\n", + cfg.max_nof_drbs_per_ue); + return drb_id_t::invalid; + } + + drb_id_t drb_id = allocate_drb_id(new_session_context, full_context, config_update, cfg.max_nof_drbs_per_ue, logger); if (drb_id == drb_id_t::invalid) { logger.warning("No more DRBs available"); return drb_id; diff --git a/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.h b/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.h index c64ac222d4..3dd04fe4cd 100644 --- a/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.h +++ b/lib/cu_cp/up_resource_manager/up_resource_manager_helpers.h @@ -62,6 +62,7 @@ up_config_update calculate_update(const cu_cp_pdu_session_resource_release_comma drb_id_t allocate_drb_id(const up_pdu_session_context_update& new_session_context, const up_context& context, const up_config_update& config_update, + uint8_t max_nof_drbs_per_ue, const srslog::basic_logger& logger); // \brief Returns valid RRC PDCP config for a given FiveQI diff --git a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp index 7d7069aa08..09fd0aa9f7 100644 --- a/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp +++ b/tests/unittests/cu_cp/cu_cp_pdu_session_resource_modify_test.cpp @@ -31,10 +31,13 @@ using namespace srsran; using namespace srs_cu_cp; +static constexpr uint8_t MAX_NOF_DRBS_PER_UE = 29; + class cu_cp_pdu_session_resource_modify_test : public cu_cp_test_environment, public ::testing::Test { public: - cu_cp_pdu_session_resource_modify_test() : cu_cp_test_environment(cu_cp_test_env_params{}) + cu_cp_pdu_session_resource_modify_test() : + cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, MAX_NOF_DRBS_PER_UE}) { // Run NG setup to completion. run_ng_setup(); @@ -462,7 +465,7 @@ TEST_F(cu_cp_pdu_session_resource_modify_test, when_many_qos_flows_are_added_pdu // Add QoS flows until maximum number of DRBs is reached unsigned transaction_id = 0; unsigned count = 8; - for (unsigned i = 2; i <= MAX_NOF_DRBS; ++i) { + for (unsigned i = 2; i <= MAX_NOF_DRBS_PER_UE; ++i) { ASSERT_TRUE(modify_pdu_session_and_add_qos_flow(psi, uint_to_drb_id(i), uint_to_qos_flow_id(i), @@ -480,7 +483,7 @@ TEST_F(cu_cp_pdu_session_resource_modify_test, when_one_to_many_qos_flows_are_ad // Add QoS flows until maximum number of DRBs is reached unsigned transaction_id = 0; unsigned count = 8; - for (unsigned i = 2; i <= MAX_NOF_DRBS; ++i) { + for (unsigned i = 2; i <= MAX_NOF_DRBS_PER_UE; ++i) { ASSERT_TRUE(modify_pdu_session_and_add_qos_flow(psi, uint_to_drb_id(i), uint_to_qos_flow_id(i), diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.cpp b/tests/unittests/cu_cp/cu_cp_test_environment.cpp index 67d14c357a..624d1b23dc 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.cpp +++ b/tests/unittests/cu_cp/cu_cp_test_environment.cpp @@ -69,13 +69,14 @@ cu_cp_test_environment::cu_cp_test_environment(cu_cp_test_env_params params_) : srslog::init(); // Create CU-CP config - cu_cp_cfg = config_helpers::make_default_cu_cp_config(); - cu_cp_cfg.services.cu_cp_executor = cu_cp_workers->exec.get(); - cu_cp_cfg.services.timers = &timers; - cu_cp_cfg.admission.max_nof_dus = params.max_nof_dus; - cu_cp_cfg.admission.max_nof_cu_ups = params.max_nof_cu_ups; - cu_cp_cfg.admission.max_nof_ues = params.max_nof_ues; - cu_cp_cfg.bearers.drb_config = config_helpers::make_default_cu_cp_qos_config_list(); + cu_cp_cfg = config_helpers::make_default_cu_cp_config(); + cu_cp_cfg.services.cu_cp_executor = cu_cp_workers->exec.get(); + cu_cp_cfg.services.timers = &timers; + cu_cp_cfg.admission.max_nof_dus = params.max_nof_dus; + cu_cp_cfg.admission.max_nof_cu_ups = params.max_nof_cu_ups; + cu_cp_cfg.admission.max_nof_ues = params.max_nof_ues; + cu_cp_cfg.admission.max_nof_drbs_per_ue = params.max_nof_drbs_per_ue; + cu_cp_cfg.bearers.drb_config = config_helpers::make_default_cu_cp_qos_config_list(); // > NGAP config for (const auto& [amf_index, amf_config] : amf_configs) { cu_cp_cfg.ngaps.push_back(cu_cp_configuration::ngap_params{&*amf_config.amf_stub, amf_config.supported_tas}); diff --git a/tests/unittests/cu_cp/cu_cp_test_environment.h b/tests/unittests/cu_cp/cu_cp_test_environment.h index 28145b68d1..77c4f2dd86 100644 --- a/tests/unittests/cu_cp/cu_cp_test_environment.h +++ b/tests/unittests/cu_cp/cu_cp_test_environment.h @@ -32,9 +32,10 @@ struct cu_cp_test_amf_config { }; struct cu_cp_test_env_params { - cu_cp_test_env_params(unsigned max_nof_cu_ups_ = 8, - unsigned max_nof_dus_ = 8, - unsigned max_nof_ues_ = 8192, + cu_cp_test_env_params(unsigned max_nof_cu_ups_ = 8, + unsigned max_nof_dus_ = 8, + unsigned max_nof_ues_ = 8192, + unsigned max_nof_drbs_per_ue_ = 8, const std::vector>& amf_config_ = {{supported_tracking_area{7, {{plmn_identity::test_value(), {{1}}}}}}}, bool load_plugins_ = false, @@ -44,6 +45,7 @@ struct cu_cp_test_env_params { max_nof_cu_ups(max_nof_cu_ups_), max_nof_dus(max_nof_dus_), max_nof_ues(max_nof_ues_), + max_nof_drbs_per_ue(max_nof_drbs_per_ue_), load_plugins(load_plugins_), start_ng_ho_func(start_ng_ho_func_), connect_amfs(connect_amfs_), @@ -58,6 +60,7 @@ struct cu_cp_test_env_params { unsigned max_nof_cu_ups; unsigned max_nof_dus; unsigned max_nof_ues; + unsigned max_nof_drbs_per_ue; bool load_plugins; void* start_ng_ho_func; connect_amfs_func connect_amfs; diff --git a/tests/unittests/cu_cp/up_resource_manager/up_resource_manager_test.cpp b/tests/unittests/cu_cp/up_resource_manager/up_resource_manager_test.cpp index 91287e8340..66a566ef84 100644 --- a/tests/unittests/cu_cp/up_resource_manager/up_resource_manager_test.cpp +++ b/tests/unittests/cu_cp/up_resource_manager/up_resource_manager_test.cpp @@ -91,7 +91,7 @@ class up_resource_manager_test : public ::testing::Test public: pdcp_config pdcp_cfg{pdcp_rb_type::drb, pdcp_rlc_mode::am}; - up_resource_manager_cfg cfg{{{uint_to_five_qi(9), {pdcp_cfg}}, {uint_to_five_qi(7), {pdcp_cfg}}}}; + up_resource_manager_cfg cfg{{{uint_to_five_qi(9), {pdcp_cfg}}, {uint_to_five_qi(7), {pdcp_cfg}}}, 8}; up_resource_manager manager{cfg}; }; From 284d2fe395c5557d61113ad8b4cf6d4eff2615d8 Mon Sep 17 00:00:00 2001 From: asaezper Date: Thu, 26 Sep 2024 10:38:17 +0200 Subject: [PATCH 142/174] ci: fix phy_testvectors tar extension --- .gitlab/ci/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab/ci/release.yml b/.gitlab/ci/release.yml index bb8ce6442e..ffb5a7edb3 100644 --- a/.gitlab/ci/release.yml +++ b/.gitlab/ci/release.yml @@ -111,10 +111,10 @@ generate testvector tar gz: interruptible: false image: ubuntu:24.04 script: - - find . -name "*.tar.gz" -exec tar -rvf phy_testvectors.tar.gz {} \; + - find . -name "*.tar.gz" -exec tar -rvf phy_testvectors.tar {} \; artifacts: paths: - - phy_testvectors.tar.gz + - phy_testvectors.tar expire_in: "30 days" coverity-agpl: @@ -266,7 +266,7 @@ release public: artifacts: true variables: GIT_STRATEGY: none - ARTIFACT: phy_testvectors.tar.gz + ARTIFACT: phy_testvectors.tar PUBLIC_NAME: "" PUBLIC_REPO: "" PUBLIC_BRANCH: "" @@ -299,7 +299,7 @@ release public: https://api.github.com/repos/${PUBLIC_REPO}/releases \ -d "{\"tag_name\":\"${PUBLIC_TAG}\",\"target_commitish\":\"${PUBLIC_BRANCH}\",\"name\":\"${PUBLIC_RELEASE_NAME}\",\"body\":\"${PUBLIC_RELEASE_NOTES}\",\"draft\":false,\"prerelease\":false,\"generate_release_notes\":false}" | jq '.id') - # Push testvector.tar.gz to release + # Push ${ARTIFACT} to release - | curl -L \ -X POST \ From c54baf16249ed8866ed37b4069fff94b74d168c4 Mon Sep 17 00:00:00 2001 From: asaezper Date: Thu, 26 Sep 2024 13:22:26 +0200 Subject: [PATCH 143/174] ci,e2e: enable rlc metrics in viavi --- tests/e2e/tests/viavi.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index b9542da9f0..3e25768019 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -335,6 +335,7 @@ def _test_viavi( "enable_qos_viavi": test_declaration.enable_qos_viavi, "nof_antennas_dl": 4, "nof_antennas_ul": 1, + "rlc_metrics": True, }, }, } From 3cef2f504251dabccdfe9ca7f07d5553002ae9f3 Mon Sep 17 00:00:00 2001 From: asaezper Date: Thu, 26 Sep 2024 15:25:11 +0200 Subject: [PATCH 144/174] ci,e2e: ims tests --- .gitlab-ci.yml | 3 - .gitlab/ci/e2e.yml | 17 +++++ .gitlab/ci/e2e/.env | 2 +- .../ci/e2e/retina_request_android_callbox.yml | 69 +++++++++++++++++ tests/e2e/tests/ping.py | 76 +++++++++++++++++-- tests/e2e/tests/steps/configuration.py | 2 + tests/e2e/tests/steps/stub.py | 16 ++++ 7 files changed, 175 insertions(+), 10 deletions(-) create mode 100644 .gitlab/ci/e2e/retina_request_android_callbox.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bfe8eff139..61aec530d4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -321,9 +321,6 @@ e2e tests tox: before_script: - apk add build-base extends: .tox - parallel: - matrix: - - PYTHON_VERSION: ["3.9", "3.10", "3.11", "3.12"] ################################################################################ ## Build + Unit Tests + Integration tests diff --git a/.gitlab/ci/e2e.yml b/.gitlab/ci/e2e.yml index cbdcd1f14c..2619305b08 100644 --- a/.gitlab/ci/e2e.yml +++ b/.gitlab/ci/e2e.yml @@ -556,6 +556,23 @@ android b200: GROUP: "rf" TESTBED: "android_b200" MARKERS: "android" + KEYWORDS: "not ims" + E2E_LOG_LEVEL: "warning" + KUBECONFIG_VAR_NAME: "RETINA_NAMESPACE_KUBECONFIG" + KUBECONFIG_VAR_NAME_EXTRA: "RETINA_NAMESPACE_KUBECONFIG_EXTRA" + needs: + - job: "basic relwithdeb" + artifacts: true + - *retina-needs + +android b200 IMS: + stage: rf + extends: .e2e-run + variables: + GROUP: "rf" + TESTBED: "android_callbox" + MARKERS: "android" + KEYWORDS: "ims" E2E_LOG_LEVEL: "warning" KUBECONFIG_VAR_NAME: "RETINA_NAMESPACE_KUBECONFIG" KUBECONFIG_VAR_NAME_EXTRA: "RETINA_NAMESPACE_KUBECONFIG_EXTRA" diff --git a/.gitlab/ci/e2e/.env b/.gitlab/ci/e2e/.env index aefba9a81d..7a0e9fa4e2 100644 --- a/.gitlab/ci/e2e/.env +++ b/.gitlab/ci/e2e/.env @@ -1,6 +1,6 @@ SRSGNB_REGISTRY_URI=registry.gitlab.com/softwareradiosystems/srsgnb RETINA_REGISTRY_PREFIX=registry.gitlab.com/softwareradiosystems/ci/retina -RETINA_VERSION=0.52.24 +RETINA_VERSION=0.53.0 UBUNTU_VERSION=24.04 AMARISOFT_VERSION=2023-09-08 SRSUE_VERSION=23.11 diff --git a/.gitlab/ci/e2e/retina_request_android_callbox.yml b/.gitlab/ci/e2e/retina_request_android_callbox.yml new file mode 100644 index 0000000000..482084e174 --- /dev/null +++ b/.gitlab/ci/e2e/retina_request_android_callbox.yml @@ -0,0 +1,69 @@ +# +# Copyright 2013-2024 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +- name: android-ue + type: ue + image: ${RETINA_REGISTRY_PREFIX}/android:${RETINA_VERSION} + requirements: + arch: amd64 + cpu: + requests: 1 + limits: 1 + memory: + requests: "2G" + limits: "2G" + ephemeral-storage: + requests: "6G" + limits: "6G" + resources: + - type: android + model: xiaomi-12-lite + +- name: srs-gnb + type: gnb + image: ${RETINA_REGISTRY_PREFIX}/srsgnb:${RETINA_VERSION} + host_network: true + requirements: + arch: amd64 + cpu: + requests: 6 + limits: 6 + memory: + requests: "10G" + limits: "10G" + ephemeral-storage: + requests: "6G" + limits: "6G" + resources: + - type: sdr + model: b200 + environment: + - PATH: ${PATH}:/builds/softwareradiosystems/srsgnb/build/apps/gnb + shared_files: + - local_path: ${GNB_BINARY_PATH} + remote_path: /usr/local/bin/gnb + is_executable: true + +- name: amarisoft-mme + type: 5gc + image: ${RETINA_REGISTRY_PREFIX}/amarisoft5gc-remote:${RETINA_VERSION} + taints: ["purpose=retina"] + requirements: + arch: amd64 + cpu: + requests: 4 + limits: 4 + memory: + requests: "4G" + limits: "4G" + ephemeral-storage: + requests: "6G" + limits: "6G" + resources: + - type: emulator + model: callbox diff --git a/tests/e2e/tests/ping.py b/tests/e2e/tests/ping.py index 5794aaeb43..4972d3efa1 100644 --- a/tests/e2e/tests/ping.py +++ b/tests/e2e/tests/ping.py @@ -25,7 +25,7 @@ from retina.protocol.ue_pb2_grpc import UEStub from .steps.configuration import configure_test_parameters, get_minimum_sample_rate_for_bandwidth -from .steps.stub import ping, start_network, stop, ue_start_and_attach, ue_stop +from .steps.stub import ping, start_network, stop, ue_start_and_attach, ue_stop, validate_ue_registered_via_ims @mark.parametrize( @@ -81,6 +81,60 @@ def test_android( ) +@mark.parametrize( + "ims_mode", + ( + param(""), + param("enabled"), + param("not_registering"), + ), +) +@mark.parametrize( + "band, common_scs, bandwidth", + ( + param(3, 15, 10, id="band:%s-scs:%s-bandwidth:%s"), + param(78, 30, 20, id="band:%s-scs:%s-bandwidth:%s"), + ), +) +@mark.android +@mark.flaky( + reruns=2, + only_rerun=["failed to start", "Exception calling application", "Attach timeout reached", "Some packages got lost"], +) +# pylint: disable=too-many-arguments,too-many-positional-arguments +def test_android_ims( + retina_manager: RetinaTestManager, + retina_data: RetinaTestData, + ue: UEStub, # pylint: disable=invalid-name + fivegc: FiveGCStub, + gnb: GNBStub, + band: int, + common_scs: int, + bandwidth: int, + ims_mode: str, +): + """ + Android IMS Pings + """ + + _ping( + retina_manager=retina_manager, + retina_data=retina_data, + ue_array=(ue,), + gnb=gnb, + fivegc=fivegc, + band=band, + common_scs=common_scs, + bandwidth=bandwidth, + sample_rate=get_minimum_sample_rate_for_bandwidth(bandwidth), + global_timing_advance=-1, + time_alignment_calibration="auto", + warning_as_errors=False, + always_download_artifacts=True, + ims_mode=ims_mode, + ) + + @mark.parametrize( "reattach_count", ( @@ -352,6 +406,7 @@ def _ping( ue_stop_timeout: int = 0, plmn: Optional[PLMN] = None, enable_security_mode: bool = False, + ims_mode: str = "", ): logging.info("Ping Test") @@ -367,6 +422,7 @@ def _ping( n3_enable=True, log_ip_level="debug", enable_security_mode=enable_security_mode, + ims_mode=ims_mode, ) configure_artifacts( retina_data=retina_data, @@ -375,14 +431,22 @@ def _ping( start_network(ue_array, gnb, fivegc, gnb_pre_cmd=pre_command, gnb_post_cmd=post_command, plmn=plmn) ue_attach_info_dict = ue_start_and_attach(ue_array, gnb, fivegc) - ping(ue_attach_info_dict, fivegc, ping_count) - # reattach and repeat if requested - for _ in range(reattach_count): - ue_stop(ue_array, retina_data) - ue_attach_info_dict = ue_start_and_attach(ue_array, gnb, fivegc) + try: ping(ue_attach_info_dict, fivegc, ping_count) + # reattach and repeat if requested + for _ in range(reattach_count): + ue_stop(ue_array, retina_data) + ue_attach_info_dict = ue_start_and_attach(ue_array, gnb, fivegc) + ping(ue_attach_info_dict, fivegc, ping_count) + except Failed as err: + if not ims_mode or ims_mode == "enabled": + raise err from None + + if ims_mode: + validate_ue_registered_via_ims(ue_array if ims_mode == "enabled" else tuple(), fivegc) + # final stop stop( ue_array, diff --git a/tests/e2e/tests/steps/configuration.py b/tests/e2e/tests/steps/configuration.py index 3e40168a4d..24854f992c 100644 --- a/tests/e2e/tests/steps/configuration.py +++ b/tests/e2e/tests/steps/configuration.py @@ -44,6 +44,7 @@ def configure_test_parameters( enable_dddsu: bool = False, nof_antennas_dl: int = 1, nof_antennas_ul: int = 1, + ims_mode: str = "", ): """ Configure test parameters @@ -85,6 +86,7 @@ def configure_test_parameters( "nof_antennas_ul": nof_antennas_ul, }, }, + "5gc": {"parameters": {"ims_mode": ims_mode}}, } if n3_enable is not None and n3_enable: retina_data.test_config["gnb"]["parameters"]["pcap"] = True diff --git a/tests/e2e/tests/steps/stub.py b/tests/e2e/tests/steps/stub.py index 720f817f06..45800146ac 100644 --- a/tests/e2e/tests/steps/stub.py +++ b/tests/e2e/tests/steps/stub.py @@ -569,6 +569,22 @@ def ue_validate_no_reattaches(ue_stub: UEStub): logging.error("UE [%s] had multiples rrc setups:\n%s", id(ue_stub), MessageToString(messages, indent=2)) +def validate_ue_registered_via_ims(ue_stub_array: Sequence[UEStub], core: FiveGCStub) -> None: + """ + Fails if the UEs are not registered in IMS + """ + expected_subscriber_array = tuple( + sorted([ue_stub.GetDefinition(Empty()).subscriber.imsi for ue_stub in ue_stub_array]) + ) + logging.info("IMSI of expected UEs in IMS: %s", expected_subscriber_array) + registered_subscriber_array = tuple( + sorted([subscriber.imsi for subscriber in core.GetImsRegisteredUESubscriberArray(Empty()).value]) + ) + logging.info("IMSI of registered UEs in IMS: %s", registered_subscriber_array) + if expected_subscriber_array != registered_subscriber_array: + pytest.fail("IMS Registered Subscriber array mismatch!") + + def stop( ue_array: Sequence[UEStub], gnb: Optional[GNBStub], From d29272a8308deb4da9fea66a86e9ddf1eaa47d75 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 26 Sep 2024 17:05:18 +0200 Subject: [PATCH 145/174] phy: fix SRS related --- .../upper/signal_processors/srs/formatters.h | 18 ++++++++++++++++-- .../srsran/ran/srs/srs_resource_formatter.h | 6 ++++-- lib/fapi_adaptor/mac/messages/srs.cpp | 3 +-- .../srs/srs_estimator_generic_impl.cpp | 3 +++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/srsran/phy/upper/signal_processors/srs/formatters.h b/include/srsran/phy/upper/signal_processors/srs/formatters.h index 62164ea2ba..7b8c714f85 100644 --- a/include/srsran/phy/upper/signal_processors/srs/formatters.h +++ b/include/srsran/phy/upper/signal_processors/srs/formatters.h @@ -66,8 +66,22 @@ struct formatter { -> decltype(std::declval().out()) { helper.format_always(ctx, "t_align={:.1}us", config.time_alignment.time_alignment * 1e6); - helper.format_always(ctx, "noise_var={}", config.noise_variance); - helper.format_if_verbose(ctx, "H={}", config.channel_matrix); + helper.format_always(ctx, "noise_var={:.3e}", config.noise_variance); + + // Get matrix Frobenius norm. + float frobenius_norm = config.channel_matrix.frobenius_norm(); + + if (std::isnormal(frobenius_norm)) { + // Normalize matrix. + srsran::srs_channel_matrix norm_matrix = config.channel_matrix; + norm_matrix *= 1.0F / frobenius_norm; + + // Print norm and matrix. + helper.format_if_verbose(ctx, "H={:.3e} * {}", frobenius_norm, norm_matrix); + } else { + // Do not print anything if there are no coefficients. + helper.format_if_verbose(ctx, "H=[]"); + } return ctx.out(); } diff --git a/include/srsran/ran/srs/srs_resource_formatter.h b/include/srsran/ran/srs/srs_resource_formatter.h index af8b13179c..4537a5ede6 100644 --- a/include/srsran/ran/srs/srs_resource_formatter.h +++ b/include/srsran/ran/srs/srs_resource_formatter.h @@ -35,8 +35,10 @@ struct formatter { -> decltype(std::declval().out()) { helper.format_if_verbose(ctx, "nof_antenna_ports={}", resource.nof_antenna_ports); - helper.format_if_verbose(ctx, "nof_symbols={}", resource.nof_symbols); - helper.format_if_verbose(ctx, "start_symbol={}", resource.start_symbol); + helper.format_if_verbose(ctx, + "symb=[{}, {})", + resource.start_symbol, + resource.start_symbol.value() + static_cast(resource.nof_symbols)); helper.format_if_verbose(ctx, "configuration_index={}", resource.configuration_index); helper.format_if_verbose(ctx, "sequence_id={}", resource.sequence_id); helper.format_if_verbose(ctx, "bandwidth_index={}", resource.bandwidth_index); diff --git a/lib/fapi_adaptor/mac/messages/srs.cpp b/lib/fapi_adaptor/mac/messages/srs.cpp index 5afd45b0e1..19c39a945f 100644 --- a/lib/fapi_adaptor/mac/messages/srs.cpp +++ b/lib/fapi_adaptor/mac/messages/srs.cpp @@ -40,8 +40,7 @@ void fapi_adaptor::convert_srs_mac_to_fapi(fapi::ul_srs_pdu_builder& builder, co builder.set_comb_params(mac_pdu.tx_comb, mac_pdu.comb_offset); // Timing parameters. - static constexpr unsigned time_start_position = 0; - builder.set_timing_params(time_start_position, mac_pdu.t_srs_period, mac_pdu.t_offset); + builder.set_timing_params(mac_pdu.symbols.start(), mac_pdu.t_srs_period, mac_pdu.t_offset); // Rest of the parameters. builder.set_srs_params(mac_pdu.nof_antenna_ports, diff --git a/lib/phy/upper/signal_processors/srs/srs_estimator_generic_impl.cpp b/lib/phy/upper/signal_processors/srs/srs_estimator_generic_impl.cpp index 183f0d97a9..09a3ccaf84 100644 --- a/lib/phy/upper/signal_processors/srs/srs_estimator_generic_impl.cpp +++ b/lib/phy/upper/signal_processors/srs/srs_estimator_generic_impl.cpp @@ -177,5 +177,8 @@ srs_estimator_result srs_estimator_generic_impl::estimate(const resource_grid_re } } + // Set noise variance to zero. + result.noise_variance = near_zero; + return result; } From 1e4e2d73075088de2397539136643ca4fdbfee2b Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Thu, 26 Sep 2024 14:07:49 +0200 Subject: [PATCH 146/174] cu_cp: add console output for failed du connections --- lib/cu_cp/cu_cp_controller/du_connection_manager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp b/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp index b3b0fb4f35..22bf7575a7 100644 --- a/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp +++ b/lib/cu_cp/cu_cp_controller/du_connection_manager.cpp @@ -134,7 +134,10 @@ du_connection_manager::handle_new_du_connection(std::unique_ptr= max_nof_dus) { - logger.warning("Rejecting new DU connection. Cause: Maximum number of DUs {} reached.", max_nof_dus); + logger.warning("Rejecting new DU connection. Cause: Maximum number of DUs connected ({})", max_nof_dus); + fmt::print("DU connection failed. Cause: Maximum number of DUs connected ({}). To increase the number of allowed " + "DUs change the \"--max_nof_dus\" in the CU-CP configuration\n", + max_nof_dus); return nullptr; } @@ -147,7 +150,7 @@ du_connection_manager::handle_new_du_connection(std::unique_ptr Date: Thu, 19 Sep 2024 17:21:30 +0200 Subject: [PATCH 147/174] du_high: review use of transform precoder du: fix DCI Format in transform precoding du: review MAC transform precoding related --- .../du_high/du_high_config_translators.cpp | 7 + .../du_high/du_high_config_validator.cpp | 20 +- include/srsran/ran/pusch/pusch_mcs.h | 16 +- lib/ran/pusch/pusch_mcs.cpp | 22 +- .../common_scheduling/ra_scheduler.cpp | 3 +- lib/scheduler/config/cell_configuration.h | 15 + lib/scheduler/config/ue_configuration.h | 14 + lib/scheduler/support/dci_builder.cpp | 12 +- lib/scheduler/support/mcs_calculator.h | 6 +- lib/scheduler/support/mcs_tbs_calculator.cpp | 7 +- lib/scheduler/support/sch_pdu_builder.cpp | 57 +-- lib/scheduler/support/sch_pdu_builder.h | 1 + lib/scheduler/ue_scheduling/ue_cell.cpp | 12 +- .../ue_scheduling/ue_cell_grid_allocator.cpp | 10 + .../ue_scheduling/ue_fallback_scheduler.cpp | 23 +- .../ue_link_adaptation_controller.cpp | 22 +- .../ue_link_adaptation_controller.h | 3 +- .../channel_processors/pxsch_bler_test.cpp | 6 +- .../ran/pusch/pusch_mcs_table_test.cpp | 351 +++++++++--------- 19 files changed, 350 insertions(+), 257 deletions(-) diff --git a/apps/units/flexible_du/du_high/du_high_config_translators.cpp b/apps/units/flexible_du/du_high/du_high_config_translators.cpp index e5ff9de10d..07ca6835ca 100644 --- a/apps/units/flexible_du/du_high/du_high_config_translators.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_translators.cpp @@ -563,6 +563,13 @@ std::vector srsran::generate_du_cell_config(const du_hig uint_to_dmrs_additional_positions(base_cell.pusch_cfg.dmrs_add_pos); // Set UL MCS table. out_cell.ue_ded_serv_cell_cfg.ul_config->init_ul_bwp.pusch_cfg->mcs_table = base_cell.pusch_cfg.mcs_table; + // Configure PUSCH transform precoding. + if (base_cell.pusch_cfg.enable_transform_precoding) { + pusch_config& pusch_cfg = out_cell.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.pusch_cfg.value(); + pusch_cfg.trans_precoder = pusch_config::transform_precoder::enabled; + pusch_cfg.pusch_mapping_type_a_dmrs.value().trans_precoder_enabled.emplace( + dmrs_uplink_config::transform_precoder_enabled{std::nullopt, false, false}); + } if (not out_cell.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.pusch_cfg.value().uci_cfg.has_value()) { out_cell.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.pusch_cfg.value().uci_cfg.emplace(); } diff --git a/apps/units/flexible_du/du_high/du_high_config_validator.cpp b/apps/units/flexible_du/du_high/du_high_config_validator.cpp index 8119638e3a..24993aa40f 100644 --- a/apps/units/flexible_du/du_high/du_high_config_validator.cpp +++ b/apps/units/flexible_du/du_high/du_high_config_validator.cpp @@ -341,15 +341,18 @@ static bool validate_pusch_cell_unit_config(const du_high_unit_pusch_config& con return false; } + // Modulation and Code Scheme MCS ranges are given in TS38.214 Section 6.1.4.2. unsigned max_ue_mcs = 28; - if (config.mcs_table == pusch_mcs_table::qam256) { + if ((config.mcs_table == pusch_mcs_table::qam256) || config.enable_transform_precoding) { max_ue_mcs = 27; } if (config.min_ue_mcs > max_ue_mcs) { - fmt::print("Invalid PUSCH min_ue_mcs (i.e., {}) for the selected MCS table (i.e., {}).\n", - config.min_ue_mcs, - (config.mcs_table == pusch_mcs_table::qam256) ? "qam256" : "qam64"); + fmt::print( + "Invalid PUSCH min_ue_mcs (i.e., {}) for the selected MCS table (i.e., {}) with transform precoding {}.\n", + config.min_ue_mcs, + (config.mcs_table == pusch_mcs_table::qam256) ? "qam256" : "qam64", + config.enable_transform_precoding ? "enabled" : "disabled"); return false; } @@ -373,15 +376,6 @@ static bool validate_pusch_cell_unit_config(const du_high_unit_pusch_config& con return false; } - if (config.enable_transform_precoding && !is_transform_precoding_nof_prb_valid(config.max_rb_size)) { - fmt::print("Invalid maximum UE PUSCH RB (i.e., {}) with transform precoding. The nearest lower number of PRB is {} " - "and the higher is {}.\n", - config.max_rb_size, - get_transform_precoding_nearest_lower_nof_prb_valid(config.max_rb_size), - get_transform_precoding_nearest_higher_nof_prb_valid(config.max_rb_size)); - return false; - } - if (config.end_rb < config.start_rb) { fmt::print("Invalid RB allocation range [{}, {}) for UE PUSCHs. The start_rb must be less or equal to the end_rb", config.start_rb, diff --git a/include/srsran/ran/pusch/pusch_mcs.h b/include/srsran/ran/pusch/pusch_mcs.h index d81f7657c3..92ddb908dd 100644 --- a/include/srsran/ran/pusch/pusch_mcs.h +++ b/include/srsran/ran/pusch/pusch_mcs.h @@ -25,21 +25,19 @@ enum class pusch_mcs_table { qam256 = 1, /// Identifies MCS index table 3, TS38.214 Table 5.1.3.1-3. qam64LowSe = 2, - /// Identifies MCS index table 1 with transform precoding, TS38.214 Table 6.1.4.1-1. - qam64_tp = 3, - /// Identifies MCS index table 2 with transform precoding, TS38.214 Table 6.1.4.1-2. - qam64LowSe_tp = 4, }; /// \brief Gets the Modulation and Coding Scheme configuration for PUSCH. /// /// Reserved target code rates and spectral efficiencies are indicated with zero. /// -/// \param[in] table MCS table. -/// \param[in] index MCS index. -/// \param[in] tp_pi2bpsk_present Set to true if higher layer parameter \e tp-pi2BPSK is enabled. See TS38.331 -/// Section 6.3.2 Information Element \e PUSCH-Config for more information. +/// \param[in] table MCS table. +/// \param[in] index MCS index. +/// \param[in] use_transform_precoder Set to true if transform precoding is enabled. +/// \param[in] tp_pi2bpsk_present Set to true if higher layer parameter \e tp-pi2BPSK is enabled. See TS38.331 +/// Section 6.3.2 Information Element \e PUSCH-Config for more information. /// \return Modulation and Coding Scheme parameters. -sch_mcs_description pusch_mcs_get_config(pusch_mcs_table table, sch_mcs_index index, bool tp_pi2bpsk_present); +sch_mcs_description +pusch_mcs_get_config(pusch_mcs_table table, sch_mcs_index index, bool use_transform_precoder, bool tp_pi2bpsk_present); } // namespace srsran diff --git a/lib/ran/pusch/pusch_mcs.cpp b/lib/ran/pusch/pusch_mcs.cpp index 000c570c5a..fe379519f0 100644 --- a/lib/ran/pusch/pusch_mcs.cpp +++ b/lib/ran/pusch/pusch_mcs.cpp @@ -14,7 +14,10 @@ using namespace srsran; -sch_mcs_description srsran::pusch_mcs_get_config(pusch_mcs_table table, sch_mcs_index index, bool tp_pi2bpsk_present) +sch_mcs_description srsran::pusch_mcs_get_config(pusch_mcs_table table, + sch_mcs_index index, + bool use_transform_precoder, + bool tp_pi2bpsk_present) { // TS38.214 Table 6.1.4.1-1. static constexpr std::array MCS_INDEX_TABLE_1_TP = { @@ -50,27 +53,30 @@ sch_mcs_description srsran::pusch_mcs_get_config(pusch_mcs_table table, sch_mcs_ {modulation_scheme::QAM16, 616.0F}, {modulation_scheme::QAM16, 658.0F}, {modulation_scheme::QAM16, 699.0F}, {modulation_scheme::QAM16, 772.0F}, {modulation_scheme::QAM64, 567.0F}, {modulation_scheme::QAM64, 616.0F}, - {modulation_scheme::QAM64, 666.5F}, {modulation_scheme::QAM64, 772.0F}, + {modulation_scheme::QAM64, 666.0F}, {modulation_scheme::QAM64, 772.0F}, {modulation_scheme::PI_2_BPSK, 0.0F}, {modulation_scheme::QPSK, 0.0F}, {modulation_scheme::QAM16, 0.0F}, {modulation_scheme::QAM64, 0.0F}}}; + // Use PDSCH tables if no transform precoding is selected. + if (!use_transform_precoder || (table == pusch_mcs_table::qam256)) { + return pdsch_mcs_get_config(static_cast(table), index); + } + // Return the MCS configuration from the selected table. sch_mcs_description result = {}; switch (table) { case pusch_mcs_table::qam64: - case pusch_mcs_table::qam256: - case pusch_mcs_table::qam64LowSe: - // Reuses PDSCH tables. - return pdsch_mcs_get_config(static_cast(table), index); - case pusch_mcs_table::qam64_tp: result = MCS_INDEX_TABLE_1_TP[index.to_uint()]; break; - case pusch_mcs_table::qam64LowSe_tp: + case pusch_mcs_table::qam64LowSe: result = MCS_INDEX_TABLE_2_TP[index.to_uint()]; break; + default: + break; } if (result.modulation == modulation_scheme::PI_2_BPSK && !tp_pi2bpsk_present) { + result.modulation = modulation_scheme::QPSK; result.target_code_rate /= 2; } diff --git a/lib/scheduler/common_scheduling/ra_scheduler.cpp b/lib/scheduler/common_scheduling/ra_scheduler.cpp index 03b319ec55..93b5a6f355 100644 --- a/lib/scheduler/common_scheduling/ra_scheduler.cpp +++ b/lib/scheduler/common_scheduling/ra_scheduler.cpp @@ -157,7 +157,8 @@ void ra_scheduler::precompute_msg3_pdus() static const unsigned nof_oh_prb = 0; static const unsigned nof_layers = 1; - msg3_mcs_config = pusch_mcs_get_config(pusch_mcs_table::qam64, sched_cfg.msg3_mcs_index, false); + msg3_mcs_config = pusch_mcs_get_config( + pusch_mcs_table::qam64, sched_cfg.msg3_mcs_index, cell_cfg.use_msg3_transform_precoder(), false); const auto& pusch_td_alloc_list = get_pusch_time_domain_resource_table(get_pusch_cfg()); diff --git a/lib/scheduler/config/cell_configuration.h b/lib/scheduler/config/cell_configuration.h index aabc61789b..547aaa1523 100644 --- a/lib/scheduler/config/cell_configuration.h +++ b/lib/scheduler/config/cell_configuration.h @@ -155,6 +155,21 @@ class cell_configuration : dl_cfg_common.init_dl_bwp.pdcch_common.coreset0.value(); } + /// \brief Determines the use of transform precoding according to the parameter \e msg3-transformPrecoder. + /// + /// The UE determines the use of the transform precoder in TS 38.214 Section 6.1.3. It uses this parameter when a + /// PUSCH is scheduled by: + /// - a RAR UL grant; + /// - DCI Format 0_0; or + /// - DCI Format 0_1 and the parameter \e transformPrecoder in \e pusch-Config is not present. + bool use_msg3_transform_precoder() const + { + if (!ul_cfg_common.init_ul_bwp.rach_cfg_common) { + return false; + } + return ul_cfg_common.init_ul_bwp.rach_cfg_common->msg3_transform_precoder; + } + private: /// Vector circularly indexed by slot with the list of nof active DL/UL symbols per slot. std::vector dl_symbols_per_slot_lst; diff --git a/lib/scheduler/config/ue_configuration.h b/lib/scheduler/config/ue_configuration.h index 1045d30f39..a695d43688 100644 --- a/lib/scheduler/config/ue_configuration.h +++ b/lib/scheduler/config/ue_configuration.h @@ -148,6 +148,20 @@ class ue_cell_configuration /// Get the number of active DL ports for this UE. unsigned get_nof_dl_ports() const { return nof_dl_ports; } + /// Determines the use of transform precoding for DCI Format 0_1 for C-RNTI. + bool use_pusch_transform_precoding_dci_0_1() const + { + // If the UE is not configured with the higher layer parameter transformPrecoder in pusch-Config, determine the + // transform precoder use according to parameter msg3-transformPrecoder. + if (!cell_cfg_ded.ul_config or !cell_cfg_ded.ul_config->init_ul_bwp.pusch_cfg or + cell_cfg_ded.ul_config->init_ul_bwp.pusch_cfg->trans_precoder == pusch_config::transform_precoder::not_set) { + return cell_cfg_common.use_msg3_transform_precoder(); + } + + // Otherwise, determine the use of transform pecoding according to transformPrecoder in pusch-Config. + return cell_cfg_ded.ul_config->init_ul_bwp.pusch_cfg->trans_precoder == pusch_config::transform_precoder::enabled; + } + private: void configure_bwp_common_cfg(bwp_id_t bwpid, const bwp_downlink_common& bwp_dl_common); void configure_bwp_common_cfg(bwp_id_t bwpid, const bwp_uplink_common& bwp_ul_common); diff --git a/lib/scheduler/support/dci_builder.cpp b/lib/scheduler/support/dci_builder.cpp index c154616fd2..b18e4930b7 100644 --- a/lib/scheduler/support/dci_builder.cpp +++ b/lib/scheduler/support/dci_builder.cpp @@ -401,9 +401,15 @@ void srsran::build_dci_f0_1_c_rnti(dci_ul_info& dci, f0_1.srs_request = 0; f0_1.dmrs_seq_initialization = 0; // TODO: Set proper value based on nof. layers used. See TS 38.212, clause 7.3.1.1.2. - // PHY does not support nof. DMRS CDM groups(s) without data other than 2, hence selected antenna port value from - // Table 7.3.1.1.2-8 in TS 38.212 based on assumption of max. rank 1 and DMRS max. length 1. - f0_1.antenna_ports = 2; + if (ue_cell_cfg.use_pusch_transform_precoding_dci_0_1()) { + // PHY does not support DM-RS in ports other than 0, hence the selected antenna port value is chosen from Table + // 7.3.1.1.2-6 in TS 38.212 based on assumption of max. rank 1 and DMRS max. length 1. + f0_1.antenna_ports = 0; + } else { + // PHY does not support nof. DMRS CDM groups(s) without data other than 2, hence the selected antenna port value + // is chosen from Table 7.3.1.1.2-8 in TS 38.212 based on assumption of max. rank 1 and DMRS max. length 1. + f0_1.antenna_ports = 2; + } // See 38.212, clause 7.3.1.1.2 - N^{UL,BWP}_RB for C-RNTI. const vrb_interval vrbs = rb_helper::crb_to_vrb_ul_non_interleaved(crbs, active_ul_bwp.crbs.start()); diff --git a/lib/scheduler/support/mcs_calculator.h b/lib/scheduler/support/mcs_calculator.h index f219bc346a..a356312417 100644 --- a/lib/scheduler/support/mcs_calculator.h +++ b/lib/scheduler/support/mcs_calculator.h @@ -33,9 +33,11 @@ std::optional map_cqi_to_mcs(unsigned cqi, pdsch_mcs_table mcs_ta sch_mcs_index map_snr_to_mcs_ul(double snr, pusch_mcs_table mcs_table); /// \brief Retrieves the maximum MCS value for a given MCS table. -inline sch_mcs_index get_max_mcs_ul(pusch_mcs_table mcs_table) +/// +/// The MCS value ranges are given in TS 38.214 Section 6.1.4.2. +inline sch_mcs_index get_max_mcs_ul(pusch_mcs_table mcs_table, bool transform_precoding) { - return mcs_table == pusch_mcs_table::qam256 ? 27 : 28; + return ((mcs_table == pusch_mcs_table::qam256) or transform_precoding) ? 27 : 28; } } // namespace srsran diff --git a/lib/scheduler/support/mcs_tbs_calculator.cpp b/lib/scheduler/support/mcs_tbs_calculator.cpp index d85a755f67..04b0682540 100644 --- a/lib/scheduler/support/mcs_tbs_calculator.cpp +++ b/lib/scheduler/support/mcs_tbs_calculator.cpp @@ -232,8 +232,9 @@ std::optional srsran::compute_ul_mcs_tbs(const pusch_config_params& // but we consider the same value for UL. static const double max_supported_code_rate = 0.95; const unsigned dmrs_prbs = calculate_nof_dmrs_per_rb(pusch_cfg.dmrs); - sch_mcs_description mcs_info = pusch_mcs_get_config(pusch_cfg.mcs_table, max_mcs, pusch_cfg.tp_pi2bpsk_present); - unsigned nof_symbols = pusch_cfg.symbols.length(); + sch_mcs_description mcs_info = pusch_mcs_get_config( + pusch_cfg.mcs_table, max_mcs, pusch_cfg.use_transform_precoder, pusch_cfg.tp_pi2bpsk_present); + unsigned nof_symbols = pusch_cfg.symbols.length(); unsigned tbs_bytes = tbs_calculator_calculate(tbs_calculator_configuration{.nof_symb_sh = nof_symbols, @@ -253,7 +254,7 @@ std::optional srsran::compute_ul_mcs_tbs(const pusch_config_params& sch_mcs_index mcs = max_mcs; while (effective_code_rate > max_supported_code_rate and mcs > 0) { --mcs; - mcs_info = pusch_mcs_get_config(pusch_cfg.mcs_table, mcs, false); + mcs_info = pusch_mcs_get_config(pusch_cfg.mcs_table, mcs, pusch_cfg.use_transform_precoder, false); tbs_bytes = tbs_calculator_calculate(tbs_calculator_configuration{.nof_symb_sh = nof_symbols, .nof_dmrs_prb = dmrs_prbs, .nof_oh_prb = pusch_cfg.nof_oh_prb, diff --git a/lib/scheduler/support/sch_pdu_builder.cpp b/lib/scheduler/support/sch_pdu_builder.cpp index 1f81b13ef3..8123661aa5 100644 --- a/lib/scheduler/support/sch_pdu_builder.cpp +++ b/lib/scheduler/support/sch_pdu_builder.cpp @@ -147,10 +147,11 @@ pusch_config_params srsran::get_pusch_config_f0_0_tc_rnti(const cell_configurati pusch.symbols = pusch_td_cfg.symbols; - pusch.mcs_table = mcs_table; - pusch.nof_layers = nof_layers; - pusch.tp_pi2bpsk_present = tp_pi2bpsk_present; - pusch.tb_scaling_field = tb_scaling_field; + pusch.mcs_table = mcs_table; + pusch.nof_layers = nof_layers; + pusch.tp_pi2bpsk_present = tp_pi2bpsk_present; + pusch.use_transform_precoder = cell_cfg.use_msg3_transform_precoder(); + pusch.tb_scaling_field = tb_scaling_field; pusch.nof_oh_prb = nof_oh_prb; pusch.nof_harq_ack_bits = nof_harq_ack_bits; @@ -179,10 +180,11 @@ pusch_config_params srsran::get_pusch_config_f0_0_c_rnti(const cell_configuratio pusch.symbols = pusch_td_cfg.symbols; - pusch.mcs_table = mcs_table; - pusch.nof_layers = nof_layers; - pusch.tp_pi2bpsk_present = tp_pi2bpsk_present; - pusch.tb_scaling_field = tb_scaling_field; + pusch.mcs_table = mcs_table; + pusch.nof_layers = nof_layers; + pusch.tp_pi2bpsk_present = tp_pi2bpsk_present; + pusch.use_transform_precoder = cell_cfg.use_msg3_transform_precoder(); + pusch.tb_scaling_field = tb_scaling_field; // According to TS 38.214, Section 6.1.4.2, nof_oh_prb is set equal to xOverhead, when set; else nof_oh_prb = 0. // NOTE: x_overhead::not_set is mapped to 0. @@ -243,10 +245,11 @@ pusch_config_params srsran::get_pusch_config_f0_1_c_rnti(const ue_cell_configura pusch.symbols = pusch_td_cfg.symbols; - pusch.mcs_table = mcs_table; - pusch.nof_layers = nof_layers; - pusch.tp_pi2bpsk_present = tp_pi2bpsk_present; - pusch.tb_scaling_field = tb_scaling_field; + pusch.mcs_table = mcs_table; + pusch.nof_layers = nof_layers; + pusch.tp_pi2bpsk_present = tp_pi2bpsk_present; + pusch.use_transform_precoder = ue_cell_cfg.use_pusch_transform_precoding_dci_0_1(); + pusch.tb_scaling_field = tb_scaling_field; // According to TS 38.214, Section 6.1.4.2, nof_oh_prb is set equal to xOverhead, when set; else nof_oh_prb = 0. // NOTE: x_overhead::not_set is mapped to 0. @@ -601,7 +604,8 @@ void srsran::build_pusch_f0_0_tc_rnti(pusch_information& pusch const dci_0_0_tc_rnti_configuration& dci_cfg, const crb_interval& crbs, bool is_new_data) -{ // TODO. +{ + // TODO. pusch.intra_slot_freq_hopping = false; pusch.pusch_second_hop_prb = 0; pusch.tx_direct_current_location = @@ -617,14 +621,14 @@ void srsran::build_pusch_f0_0_tc_rnti(pusch_information& pusch pusch.rbs = vrb_interval{prbs.start(), prbs.stop()}; pusch.symbols = pusch_cfg.symbols; + // Determine transform precoding. + pusch.transform_precoding = cell_cfg.use_msg3_transform_precoder(); + // MCS. pusch.mcs_table = pusch_cfg.mcs_table; pusch.mcs_index = dci_cfg.modulation_coding_scheme; - pusch.mcs_descr = pusch_mcs_get_config(pusch.mcs_table, pusch.mcs_index, false); + pusch.mcs_descr = pusch_mcs_get_config(pusch.mcs_table, pusch.mcs_index, pusch.transform_precoding, false); - // TS 38.214, 6.1.3. - "transform precoding either 'enabled' or 'disabled' according to the higher layer configured - // parameter msg3-transformPrecoder". - pusch.transform_precoding = cell_cfg.ul_cfg_common.init_ul_bwp.rach_cfg_common->msg3_transform_precoder; // As per TS 38.211, Section 6.3.1.1, n_ID is set to Physical Cell ID for TC-RNTI. pusch.n_id = cell_cfg.pci; pusch.nof_layers = pusch_cfg.nof_layers; @@ -667,15 +671,19 @@ void srsran::build_pusch_f0_0_c_rnti(pusch_information& pusch, pusch.rbs = vrb_interval{prbs.start(), prbs.stop()}; pusch.symbols = pusch_cfg.symbols; + // The use of the transform precoder for PUSCH scheduled via DCI Format 0_0 is determined by the parameter + // msg3-transformPrecoder. + pusch.transform_precoding = cell_cfg.use_msg3_transform_precoder(); + // MCS. pusch.mcs_table = pusch_cfg.mcs_table; pusch.mcs_index = dci_cfg.modulation_coding_scheme; - pusch.mcs_descr = pusch_mcs_get_config(pusch.mcs_table, pusch.mcs_index, pusch_cfg.tp_pi2bpsk_present); + pusch.mcs_descr = + pusch_mcs_get_config(pusch.mcs_table, pusch.mcs_index, pusch.transform_precoding, pusch_cfg.tp_pi2bpsk_present); - pusch.transform_precoding = cell_cfg.ul_cfg_common.init_ul_bwp.rach_cfg_common->msg3_transform_precoder; - pusch.n_id = cell_cfg.pci; - pusch.dmrs = pusch_cfg.dmrs; - pusch.pusch_dmrs_id = cell_cfg.pci; + pusch.n_id = cell_cfg.pci; + pusch.dmrs = pusch_cfg.dmrs; + pusch.pusch_dmrs_id = cell_cfg.pci; // TBS. pusch.nof_layers = pusch_cfg.nof_layers; @@ -725,7 +733,10 @@ void srsran::build_pusch_f0_1_c_rnti(pusch_information& pusch, // MCS. pusch.mcs_table = pusch_cfg.mcs_table; pusch.mcs_index = dci_cfg.modulation_coding_scheme; - pusch.mcs_descr = pusch_mcs_get_config(pusch.mcs_table, pusch.mcs_index, pusch_cfg.tp_pi2bpsk_present); + pusch.mcs_descr = pusch_mcs_get_config(pusch.mcs_table, + pusch.mcs_index, + ue_cell_cfg.use_pusch_transform_precoding_dci_0_1(), + pusch_cfg.tp_pi2bpsk_present); pusch.n_id = cell_cfg.pci; pusch.pusch_dmrs_id = cell_cfg.pci; diff --git a/lib/scheduler/support/sch_pdu_builder.h b/lib/scheduler/support/sch_pdu_builder.h index 5b6f09d1d7..5ff8a44f1a 100644 --- a/lib/scheduler/support/sch_pdu_builder.h +++ b/lib/scheduler/support/sch_pdu_builder.h @@ -37,6 +37,7 @@ struct pusch_config_params { unsigned tb_scaling_field; unsigned nof_layers; bool tp_pi2bpsk_present; + bool use_transform_precoder; dmrs_information dmrs; unsigned nof_harq_ack_bits{0}; unsigned nof_csi_part1_bits{0}; diff --git a/lib/scheduler/ue_scheduling/ue_cell.cpp b/lib/scheduler/ue_scheduling/ue_cell.cpp index 38323f2d7d..0d376abb0c 100644 --- a/lib/scheduler/ue_scheduling/ue_cell.cpp +++ b/lib/scheduler/ue_scheduling/ue_cell.cpp @@ -206,8 +206,9 @@ grant_prbs_mcs ue_cell::required_ul_prbs(const pusch_time_domain_resource_alloca report_fatal_error("Unsupported PDCCH DCI UL format"); } - sch_mcs_index mcs = ue_mcs_calculator.calculate_ul_mcs(pusch_cfg.mcs_table); - sch_mcs_description mcs_config = pusch_mcs_get_config(pusch_cfg.mcs_table, mcs, false); + sch_mcs_index mcs = ue_mcs_calculator.calculate_ul_mcs(pusch_cfg.mcs_table); + sch_mcs_description mcs_config = + pusch_mcs_get_config(pusch_cfg.mcs_table, mcs, pusch_cfg.use_transform_precoder, false); const unsigned nof_symbols = static_cast(pusch_td_cfg.symbols.length()); @@ -543,9 +544,10 @@ double ue_cell::get_estimated_ul_rate(const pusch_config_params& pusch_cfg, sch_ { static constexpr unsigned NOF_BITS_PER_BYTE = 8U; - const unsigned dmrs_prbs = calculate_nof_dmrs_per_rb(pusch_cfg.dmrs); - sch_mcs_description mcs_info = pusch_mcs_get_config(pusch_cfg.mcs_table, mcs, pusch_cfg.tp_pi2bpsk_present); - unsigned nof_symbols = pusch_cfg.symbols.length(); + const unsigned dmrs_prbs = calculate_nof_dmrs_per_rb(pusch_cfg.dmrs); + sch_mcs_description mcs_info = + pusch_mcs_get_config(pusch_cfg.mcs_table, mcs, pusch_cfg.use_transform_precoder, pusch_cfg.tp_pi2bpsk_present); + unsigned nof_symbols = pusch_cfg.symbols.length(); unsigned tbs_bits = tbs_calculator_calculate(tbs_calculator_configuration{.nof_symb_sh = nof_symbols, diff --git a/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp b/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp index 629633693c..fa0c248b30 100644 --- a/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp +++ b/lib/scheduler/ue_scheduling/ue_cell_grid_allocator.cpp @@ -15,6 +15,7 @@ #include "ue_pdsch_alloc_param_candidate_searcher.h" #include "ue_pusch_alloc_param_candidate_searcher.h" #include "srsran/ran/pdcch/coreset.h" +#include "srsran/ran/transform_precoding/transform_precoding_helpers.h" #include "srsran/scheduler/scheduler_dci.h" #include "srsran/support/error_handling.h" @@ -707,6 +708,15 @@ ue_cell_grid_allocator::allocate_ul_grant(const ue_pusch_grant& grant, ran_slice // Re-apply nof. PUSCH RBs to allocate limits. mcs_prbs.n_prbs = std::max(mcs_prbs.n_prbs, expert_cfg.pusch_nof_rbs.start()); mcs_prbs.n_prbs = std::min(mcs_prbs.n_prbs, expert_cfg.pusch_nof_rbs.stop()); + // Ensure the number of PRB is valid if the transform precoder is used. The condition the PUSCH bandwidth with + // transform precoder is defined in TS 38.211 Section 6.1.3. The number of PRB must be lower than or equal to + // current number of PRB. + if ((dci_type == dci_ul_rnti_config_type::c_rnti_f0_1) + ? ue_cell_cfg.use_pusch_transform_precoding_dci_0_1() + : ue_cell_cfg.cell_cfg_common.use_msg3_transform_precoder()) { + mcs_prbs.n_prbs = + get_transform_precoding_nearest_lower_nof_prb_valid(mcs_prbs.n_prbs).value_or(mcs_prbs.n_prbs); + } } // NOTE: This should never happen, but it's safe not to proceed if we get n_prbs == 0. diff --git a/lib/scheduler/ue_scheduling/ue_fallback_scheduler.cpp b/lib/scheduler/ue_scheduling/ue_fallback_scheduler.cpp index bfaa2fb4fe..8bdf587f6a 100644 --- a/lib/scheduler/ue_scheduling/ue_fallback_scheduler.cpp +++ b/lib/scheduler/ue_scheduling/ue_fallback_scheduler.cpp @@ -18,6 +18,7 @@ #include "../support/pusch/pusch_td_resource_indices.h" #include "srsran/mac/mac_pdu_format.h" #include "srsran/ran/sch/tbs_calculator.h" +#include "srsran/ran/transform_precoding/transform_precoding_helpers.h" #include "srsran/srslog/srslog.h" using namespace srsran; @@ -1476,7 +1477,8 @@ ue_fallback_scheduler::schedule_ul_srb(ue& } else { pusch_mcs_table fallback_mcs_table = pusch_mcs_table::qam64; sch_mcs_index mcs = ue_pcell.get_ul_mcs(fallback_mcs_table); - sch_mcs_description ul_mcs_cfg = pusch_mcs_get_config(fallback_mcs_table, mcs, false); + sch_mcs_description ul_mcs_cfg = + pusch_mcs_get_config(fallback_mcs_table, mcs, cell_cfg.use_msg3_transform_precoder(), false); unsigned pending_bytes = u.pending_ul_newtx_bytes(); @@ -1499,6 +1501,25 @@ ue_fallback_scheduler::schedule_ul_srb(ue& ++prbs_tbs.nof_prbs; } + // Checks if the grant size is correct if transform precoding is enabled. + if (cell_cfg.use_msg3_transform_precoder()) { + // Obtain a valid suggestion of a valid number of PRB. + std::optional corrected_nof_prbs = + get_transform_precoding_nearest_higher_nof_prb_valid(prbs_tbs.nof_prbs); + + // If no suggestion is available, skip the slot. + if (!corrected_nof_prbs) { + logger.debug( + "ue={} rnti={} PUSCH allocation for SRB1 skipped. Cause: not possible to select a valid number of PRBs", + u.ue_index, + u.crnti); + return ul_srb_sched_outcome::next_slot; + } + + // Overwrite the number of PRBs with the valid number of PRB. + prbs_tbs.nof_prbs = corrected_nof_prbs.value(); + } + ue_grant_crbs = rb_helper::find_empty_interval_of_length(used_crbs, prbs_tbs.nof_prbs, 0); if (ue_grant_crbs.empty()) { diff --git a/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.cpp b/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.cpp index 2a981d873e..0e53677802 100644 --- a/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.cpp +++ b/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.cpp @@ -30,8 +30,9 @@ ue_link_adaptation_controller::ue_link_adaptation_controller(const cell_configur cell_cfg.expert_cfg.ue.olla_ul_snr_inc, cell_cfg.expert_cfg.ue.olla_max_ul_snr_offset); - last_ul_mcs_table = pusch_mcs_table::qam64LowSe_tp; // Set a different value to force update. - update_ul_mcs_lims(pusch_mcs_table::qam64); + // Set a different value to force update. + last_ul_mcs_table = pusch_mcs_table::qam64LowSe; + update_ul_mcs_lims(pusch_mcs_table::qam64, cell_cfg.use_msg3_transform_precoder()); } } @@ -73,7 +74,7 @@ void ue_link_adaptation_controller::handle_ul_crc_info(bool } // Update the MCS boundaries based on the chosen MCS table. - update_ul_mcs_lims(mcs_table); + update_ul_mcs_lims(mcs_table, cell_cfg.use_msg3_transform_precoder()); // Finally, run OLLA algorithm. ul_olla->update(crc, used_mcs, ul_mcs_lims); @@ -136,7 +137,7 @@ sch_mcs_index ue_link_adaptation_controller::calculate_ul_mcs(pusch_mcs_table mc // Derive MCS using the combination of estimated UL SNR + outer loop link adaptation. sch_mcs_index mcs = map_snr_to_mcs_ul(get_effective_snr(), mcs_table); - mcs = std::min(std::max(mcs, cell_cfg.expert_cfg.ue.ul_mcs.start()), cell_cfg.expert_cfg.ue.ul_mcs.stop()); + mcs = std::min(std::max(mcs, ul_mcs_lims.start()), ul_mcs_lims.stop()); return mcs; } @@ -153,13 +154,16 @@ void ue_link_adaptation_controller::update_dl_mcs_lims(pdsch_mcs_table mcs_table std::min(cell_cfg.expert_cfg.ue.dl_mcs.stop(), max_mcs)}; } -void ue_link_adaptation_controller::update_ul_mcs_lims(pusch_mcs_table mcs_table) +void ue_link_adaptation_controller::update_ul_mcs_lims(pusch_mcs_table mcs_table, bool transform_precoder) { - if (last_ul_mcs_table == mcs_table) { + if (last_ul_mcs_table == mcs_table and last_transform_precoder == transform_precoder) { return; } - last_ul_mcs_table = mcs_table; - ul_mcs_lims = interval{ - cell_cfg.expert_cfg.ue.ul_mcs.start(), std::min(cell_cfg.expert_cfg.ue.ul_mcs.stop(), get_max_mcs_ul(mcs_table))}; + last_ul_mcs_table = mcs_table; + last_transform_precoder = transform_precoder; + + ul_mcs_lims = interval{ + cell_cfg.expert_cfg.ue.ul_mcs.start(), + std::min(cell_cfg.expert_cfg.ue.ul_mcs.stop(), get_max_mcs_ul(mcs_table, transform_precoder))}; } diff --git a/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.h b/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.h index c862f8b0d1..7a9c37ec1d 100644 --- a/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.h +++ b/lib/scheduler/ue_scheduling/ue_link_adaptation_controller.h @@ -64,7 +64,7 @@ class ue_link_adaptation_controller void update_dl_mcs_lims(pdsch_mcs_table mcs_table); /// \brief Update the UL MCS boundaries based on the chosen MCS table. - void update_ul_mcs_lims(pusch_mcs_table mcs_table); + void update_ul_mcs_lims(pusch_mcs_table mcs_table, bool transform_precoder); const cell_configuration& cell_cfg; const ue_channel_state_manager& ue_ch_st; @@ -73,6 +73,7 @@ class ue_link_adaptation_controller pdsch_mcs_table last_dl_mcs_table; interval dl_mcs_lims; pusch_mcs_table last_ul_mcs_table; + bool last_transform_precoder; interval ul_mcs_lims; std::optional dl_olla; diff --git a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp index 6351955134..de30c4b217 100644 --- a/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp +++ b/tests/integrationtests/phy/upper/channel_processors/pxsch_bler_test.cpp @@ -74,10 +74,6 @@ const char* to_string(pusch_mcs_table table) return "qam256"; case pusch_mcs_table::qam64LowSe: return "qam64LowSe"; - case pusch_mcs_table::qam64_tp: - return "qam64_tp"; - case pusch_mcs_table::qam64LowSe_tp: - return "qam64LowSe_tp"; } return "invalid"; } @@ -207,7 +203,7 @@ class pxsch_bler_test srslog::fetch_basic_logger("ALL").set_level(srslog::basic_levels::warning); // Compute modulation and code scheme. - sch_mcs_description mcs_descr = pusch_mcs_get_config(mcs_table, mcs_index, false); + sch_mcs_description mcs_descr = pusch_mcs_get_config(mcs_table, mcs_index, false, false); // Frequency allocation equal to bandwidth part. static prb_interval freq_allocation = {bwp_start_rb, bwp_size_rb}; diff --git a/tests/unittests/ran/pusch/pusch_mcs_table_test.cpp b/tests/unittests/ran/pusch/pusch_mcs_table_test.cpp index 834e489fd0..08ba85b161 100644 --- a/tests/unittests/ran/pusch/pusch_mcs_table_test.cpp +++ b/tests/unittests/ran/pusch/pusch_mcs_table_test.cpp @@ -26,12 +26,6 @@ std::ostream& operator<<(std::ostream& os, const pusch_mcs_table& mcs_table) case pusch_mcs_table::qam64LowSe: fmt::print(os, "qam64LowSe"); break; - case pusch_mcs_table::qam64_tp: - fmt::print(os, "qam64TP"); - break; - case pusch_mcs_table::qam64LowSe_tp: - fmt::print(os, "qam64LowSeTP"); - break; } return os; } @@ -41,170 +35,170 @@ std::ostream& operator<<(std::ostream& os, const pusch_mcs_table& mcs_table) using namespace srsran; // Combined test parameters. MCS table and index. -using pusch_mcs_param = std::tuple; +using pusch_mcs_param = std::tuple; // Combined expected values from TS38.211 Tables 6.3.3.1-5, 6.3.3.1-6 and 6.3.3.1-7. static const std::map> pusch_mcs_expected = { - {{pusch_mcs_table::qam64, 0, false}, {2, 120.0F, 0.2344F}}, - {{pusch_mcs_table::qam64, 1, false}, {2, 157.0F, 0.3066F}}, - {{pusch_mcs_table::qam64, 2, false}, {2, 193.0F, 0.3770F}}, - {{pusch_mcs_table::qam64, 3, false}, {2, 251.0F, 0.4902F}}, - {{pusch_mcs_table::qam64, 4, false}, {2, 308.0F, 0.6016F}}, - {{pusch_mcs_table::qam64, 5, false}, {2, 379.0F, 0.7402F}}, - {{pusch_mcs_table::qam64, 6, false}, {2, 449.0F, 0.8770F}}, - {{pusch_mcs_table::qam64, 7, false}, {2, 526.0F, 1.0273F}}, - {{pusch_mcs_table::qam64, 8, false}, {2, 602.0F, 1.1758F}}, - {{pusch_mcs_table::qam64, 9, false}, {2, 679.0F, 1.3262F}}, - {{pusch_mcs_table::qam64, 10, false}, {4, 340.0F, 1.3281F}}, - {{pusch_mcs_table::qam64, 11, false}, {4, 378.0F, 1.4766F}}, - {{pusch_mcs_table::qam64, 12, false}, {4, 434.0F, 1.6953F}}, - {{pusch_mcs_table::qam64, 13, false}, {4, 490.0F, 1.9141F}}, - {{pusch_mcs_table::qam64, 14, false}, {4, 553.0F, 2.1602F}}, - {{pusch_mcs_table::qam64, 15, false}, {4, 616.0F, 2.4063F}}, - {{pusch_mcs_table::qam64, 16, false}, {4, 658.0F, 2.5703F}}, - {{pusch_mcs_table::qam64, 17, false}, {6, 438.0F, 2.5664F}}, - {{pusch_mcs_table::qam64, 18, false}, {6, 466.0F, 2.7305F}}, - {{pusch_mcs_table::qam64, 19, false}, {6, 517.0F, 3.0293F}}, - {{pusch_mcs_table::qam64, 20, false}, {6, 567.0F, 3.3223F}}, - {{pusch_mcs_table::qam64, 21, false}, {6, 616.0F, 3.6094F}}, - {{pusch_mcs_table::qam64, 22, false}, {6, 666.0F, 3.9023F}}, - {{pusch_mcs_table::qam64, 23, false}, {6, 719.0F, 4.2129F}}, - {{pusch_mcs_table::qam64, 24, false}, {6, 772.0F, 4.5234F}}, - {{pusch_mcs_table::qam64, 25, false}, {6, 822.0F, 4.8164F}}, - {{pusch_mcs_table::qam64, 26, false}, {6, 873.0F, 5.1152F}}, - {{pusch_mcs_table::qam64, 27, false}, {6, 910.0F, 5.3320F}}, - {{pusch_mcs_table::qam64, 28, false}, {6, 948.0F, 5.5547F}}, - {{pusch_mcs_table::qam64, 29, false}, {2, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64, 30, false}, {4, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64, 31, false}, {6, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam256, 0, false}, {2, 120.0F, 0.2344F}}, - {{pusch_mcs_table::qam256, 1, false}, {2, 193.0F, 0.3770F}}, - {{pusch_mcs_table::qam256, 2, false}, {2, 308.0F, 0.6016F}}, - {{pusch_mcs_table::qam256, 3, false}, {2, 449.0F, 0.8770F}}, - {{pusch_mcs_table::qam256, 4, false}, {2, 602.0F, 1.1758F}}, - {{pusch_mcs_table::qam256, 5, false}, {4, 378.0F, 1.4766F}}, - {{pusch_mcs_table::qam256, 6, false}, {4, 434.0F, 1.6953F}}, - {{pusch_mcs_table::qam256, 7, false}, {4, 490.0F, 1.9141F}}, - {{pusch_mcs_table::qam256, 8, false}, {4, 553.0F, 2.1602F}}, - {{pusch_mcs_table::qam256, 9, false}, {4, 616.0F, 2.4063F}}, - {{pusch_mcs_table::qam256, 10, false}, {4, 658.0F, 2.5703F}}, - {{pusch_mcs_table::qam256, 11, false}, {6, 466.0F, 2.7305F}}, - {{pusch_mcs_table::qam256, 12, false}, {6, 517.0F, 3.0293F}}, - {{pusch_mcs_table::qam256, 13, false}, {6, 567.0F, 3.3223F}}, - {{pusch_mcs_table::qam256, 14, false}, {6, 616.0F, 3.6094F}}, - {{pusch_mcs_table::qam256, 15, false}, {6, 666.0F, 3.9023F}}, - {{pusch_mcs_table::qam256, 16, false}, {6, 719.0F, 4.2129F}}, - {{pusch_mcs_table::qam256, 17, false}, {6, 772.0F, 4.5234F}}, - {{pusch_mcs_table::qam256, 18, false}, {6, 822.0F, 4.8164F}}, - {{pusch_mcs_table::qam256, 19, false}, {6, 873.0F, 5.1152F}}, - {{pusch_mcs_table::qam256, 20, false}, {8, 682.5F, 5.3320F}}, - {{pusch_mcs_table::qam256, 21, false}, {8, 711.0F, 5.5547F}}, - {{pusch_mcs_table::qam256, 22, false}, {8, 754.0F, 5.8906F}}, - {{pusch_mcs_table::qam256, 23, false}, {8, 797.0F, 6.2266F}}, - {{pusch_mcs_table::qam256, 24, false}, {8, 841.0F, 6.5703F}}, - {{pusch_mcs_table::qam256, 25, false}, {8, 885.0F, 6.9141F}}, - {{pusch_mcs_table::qam256, 26, false}, {8, 916.5F, 7.1602F}}, - {{pusch_mcs_table::qam256, 27, false}, {8, 948.0F, 7.4063F}}, - {{pusch_mcs_table::qam256, 28, false}, {2, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam256, 29, false}, {4, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam256, 30, false}, {6, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam256, 31, false}, {8, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64LowSe, 0, false}, {2, 30.0F, 0.0586F}}, - {{pusch_mcs_table::qam64LowSe, 1, false}, {2, 40.0F, 0.0781F}}, - {{pusch_mcs_table::qam64LowSe, 2, false}, {2, 50.0F, 0.0977F}}, - {{pusch_mcs_table::qam64LowSe, 3, false}, {2, 64.0F, 0.1250F}}, - {{pusch_mcs_table::qam64LowSe, 4, false}, {2, 78.0F, 0.1523F}}, - {{pusch_mcs_table::qam64LowSe, 5, false}, {2, 99.0F, 0.1934F}}, - {{pusch_mcs_table::qam64LowSe, 6, false}, {2, 120.0F, 0.2344F}}, - {{pusch_mcs_table::qam64LowSe, 7, false}, {2, 157.0F, 0.3066F}}, - {{pusch_mcs_table::qam64LowSe, 8, false}, {2, 193.0F, 0.3770F}}, - {{pusch_mcs_table::qam64LowSe, 9, false}, {2, 251.0F, 0.4902F}}, - {{pusch_mcs_table::qam64LowSe, 10, false}, {2, 308.0F, 0.6016F}}, - {{pusch_mcs_table::qam64LowSe, 11, false}, {2, 379.0F, 0.7402F}}, - {{pusch_mcs_table::qam64LowSe, 12, false}, {2, 449.0F, 0.8770F}}, - {{pusch_mcs_table::qam64LowSe, 13, false}, {2, 526.0F, 1.0273F}}, - {{pusch_mcs_table::qam64LowSe, 14, false}, {2, 602.0F, 1.1758F}}, - {{pusch_mcs_table::qam64LowSe, 15, false}, {4, 340.0F, 1.3281F}}, - {{pusch_mcs_table::qam64LowSe, 16, false}, {4, 378.0F, 1.4766F}}, - {{pusch_mcs_table::qam64LowSe, 17, false}, {4, 434.0F, 1.6953F}}, - {{pusch_mcs_table::qam64LowSe, 18, false}, {4, 490.0F, 1.9141F}}, - {{pusch_mcs_table::qam64LowSe, 19, false}, {4, 553.0F, 2.1602F}}, - {{pusch_mcs_table::qam64LowSe, 20, false}, {4, 616.0F, 2.4063F}}, - {{pusch_mcs_table::qam64LowSe, 21, false}, {6, 438.0F, 2.5664F}}, - {{pusch_mcs_table::qam64LowSe, 22, false}, {6, 466.0F, 2.7305F}}, - {{pusch_mcs_table::qam64LowSe, 23, false}, {6, 517.0F, 3.0293F}}, - {{pusch_mcs_table::qam64LowSe, 24, false}, {6, 567.0F, 3.3223F}}, - {{pusch_mcs_table::qam64LowSe, 25, false}, {6, 616.0F, 3.6094F}}, - {{pusch_mcs_table::qam64LowSe, 26, false}, {6, 666.0F, 3.9023F}}, - {{pusch_mcs_table::qam64LowSe, 27, false}, {6, 719.0F, 4.2129F}}, - {{pusch_mcs_table::qam64LowSe, 28, false}, {6, 772.0F, 4.5234F}}, - {{pusch_mcs_table::qam64LowSe, 29, false}, {2, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64LowSe, 30, false}, {4, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64LowSe, 31, false}, {6, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64_tp, 0, false}, {1, 240.0F, 0.2344F}}, - {{pusch_mcs_table::qam64_tp, 1, false}, {1, 314.0F, 0.3066F}}, - {{pusch_mcs_table::qam64_tp, 2, false}, {2, 193.0F, 0.3770F}}, - {{pusch_mcs_table::qam64_tp, 3, false}, {2, 251.0F, 0.4902F}}, - {{pusch_mcs_table::qam64_tp, 4, false}, {2, 308.0F, 0.6016F}}, - {{pusch_mcs_table::qam64_tp, 5, false}, {2, 379.0F, 0.7402F}}, - {{pusch_mcs_table::qam64_tp, 6, false}, {2, 449.0F, 0.8770F}}, - {{pusch_mcs_table::qam64_tp, 7, false}, {2, 526.0F, 1.0273F}}, - {{pusch_mcs_table::qam64_tp, 8, false}, {2, 602.0F, 1.1758F}}, - {{pusch_mcs_table::qam64_tp, 9, false}, {2, 679.0F, 1.3262F}}, - {{pusch_mcs_table::qam64_tp, 10, false}, {4, 340.0F, 1.3281F}}, - {{pusch_mcs_table::qam64_tp, 11, false}, {4, 378.0F, 1.4766F}}, - {{pusch_mcs_table::qam64_tp, 12, false}, {4, 434.0F, 1.6953F}}, - {{pusch_mcs_table::qam64_tp, 13, false}, {4, 490.0F, 1.9141F}}, - {{pusch_mcs_table::qam64_tp, 14, false}, {4, 553.0F, 2.1602F}}, - {{pusch_mcs_table::qam64_tp, 15, false}, {4, 616.0F, 2.4063F}}, - {{pusch_mcs_table::qam64_tp, 16, false}, {4, 658.0F, 2.5703F}}, - {{pusch_mcs_table::qam64_tp, 17, false}, {6, 466.0F, 2.7305F}}, - {{pusch_mcs_table::qam64_tp, 18, false}, {6, 517.0F, 3.0293F}}, - {{pusch_mcs_table::qam64_tp, 19, false}, {6, 567.0F, 3.3223F}}, - {{pusch_mcs_table::qam64_tp, 20, false}, {6, 616.0F, 3.6094F}}, - {{pusch_mcs_table::qam64_tp, 21, false}, {6, 666.0F, 3.9023F}}, - {{pusch_mcs_table::qam64_tp, 22, false}, {6, 719.0F, 4.2129F}}, - {{pusch_mcs_table::qam64_tp, 23, false}, {6, 772.0F, 4.5234F}}, - {{pusch_mcs_table::qam64_tp, 24, false}, {6, 822.0F, 4.8164F}}, - {{pusch_mcs_table::qam64_tp, 25, false}, {6, 873.0F, 5.1152F}}, - {{pusch_mcs_table::qam64_tp, 26, false}, {6, 910.0F, 5.3320F}}, - {{pusch_mcs_table::qam64_tp, 27, false}, {6, 948.0F, 5.5547F}}, - {{pusch_mcs_table::qam64_tp, 28, false}, {2, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64_tp, 29, false}, {2, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64_tp, 30, false}, {4, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64_tp, 31, false}, {6, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64LowSe_tp, 0, false}, {1, 60.0F, 0.0586F}}, - {{pusch_mcs_table::qam64LowSe_tp, 1, false}, {1, 80.0F, 0.0781F}}, - {{pusch_mcs_table::qam64LowSe_tp, 2, false}, {1, 100.0F, 0.0977F}}, - {{pusch_mcs_table::qam64LowSe_tp, 3, false}, {1, 128.0F, 0.1250F}}, - {{pusch_mcs_table::qam64LowSe_tp, 4, false}, {1, 156.0F, 0.1523F}}, - {{pusch_mcs_table::qam64LowSe_tp, 5, false}, {1, 198.0F, 0.1934F}}, - {{pusch_mcs_table::qam64LowSe_tp, 6, false}, {2, 120.0f, 0.2344F}}, - {{pusch_mcs_table::qam64LowSe_tp, 7, false}, {2, 157.0f, 0.3066F}}, - {{pusch_mcs_table::qam64LowSe_tp, 8, false}, {2, 193.0f, 0.3770F}}, - {{pusch_mcs_table::qam64LowSe_tp, 9, false}, {2, 251.0f, 0.4902F}}, - {{pusch_mcs_table::qam64LowSe_tp, 10, false}, {2, 308.0f, 0.6016F}}, - {{pusch_mcs_table::qam64LowSe_tp, 11, false}, {2, 379.0f, 0.7402F}}, - {{pusch_mcs_table::qam64LowSe_tp, 12, false}, {2, 449.0f, 0.8770F}}, - {{pusch_mcs_table::qam64LowSe_tp, 13, false}, {2, 526.0f, 1.0273F}}, - {{pusch_mcs_table::qam64LowSe_tp, 14, false}, {2, 602.0f, 1.1758F}}, - {{pusch_mcs_table::qam64LowSe_tp, 15, false}, {2, 679.0f, 1.3262F}}, - {{pusch_mcs_table::qam64LowSe_tp, 16, false}, {4, 378.0f, 1.4766F}}, - {{pusch_mcs_table::qam64LowSe_tp, 17, false}, {4, 434.0f, 1.6953F}}, - {{pusch_mcs_table::qam64LowSe_tp, 18, false}, {4, 490.0f, 1.9141F}}, - {{pusch_mcs_table::qam64LowSe_tp, 19, false}, {4, 553.0f, 2.1602F}}, - {{pusch_mcs_table::qam64LowSe_tp, 20, false}, {4, 616.0f, 2.4063F}}, - {{pusch_mcs_table::qam64LowSe_tp, 21, false}, {4, 658.0f, 2.5703F}}, - {{pusch_mcs_table::qam64LowSe_tp, 22, false}, {4, 699.0f, 2.7305F}}, - {{pusch_mcs_table::qam64LowSe_tp, 23, false}, {4, 772.0f, 3.0156F}}, - {{pusch_mcs_table::qam64LowSe_tp, 24, false}, {6, 567.0f, 3.3223F}}, - {{pusch_mcs_table::qam64LowSe_tp, 25, false}, {6, 616.0f, 3.6094F}}, - {{pusch_mcs_table::qam64LowSe_tp, 26, false}, {6, 666.0f, 3.9023F}}, - {{pusch_mcs_table::qam64LowSe_tp, 27, false}, {6, 772.0f, 4.5234F}}, - {{pusch_mcs_table::qam64LowSe_tp, 28, false}, {2, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64LowSe_tp, 29, false}, {2, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64LowSe_tp, 30, false}, {4, 0.0F, 0.0F}}, - {{pusch_mcs_table::qam64LowSe_tp, 31, false}, {6, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64, 0, false, false}, {2, 120.0F, 0.2344F}}, + {{pusch_mcs_table::qam64, 1, false, false}, {2, 157.0F, 0.3066F}}, + {{pusch_mcs_table::qam64, 2, false, false}, {2, 193.0F, 0.3770F}}, + {{pusch_mcs_table::qam64, 3, false, false}, {2, 251.0F, 0.4902F}}, + {{pusch_mcs_table::qam64, 4, false, false}, {2, 308.0F, 0.6016F}}, + {{pusch_mcs_table::qam64, 5, false, false}, {2, 379.0F, 0.7402F}}, + {{pusch_mcs_table::qam64, 6, false, false}, {2, 449.0F, 0.8770F}}, + {{pusch_mcs_table::qam64, 7, false, false}, {2, 526.0F, 1.0273F}}, + {{pusch_mcs_table::qam64, 8, false, false}, {2, 602.0F, 1.1758F}}, + {{pusch_mcs_table::qam64, 9, false, false}, {2, 679.0F, 1.3262F}}, + {{pusch_mcs_table::qam64, 10, false, false}, {4, 340.0F, 1.3281F}}, + {{pusch_mcs_table::qam64, 11, false, false}, {4, 378.0F, 1.4766F}}, + {{pusch_mcs_table::qam64, 12, false, false}, {4, 434.0F, 1.6953F}}, + {{pusch_mcs_table::qam64, 13, false, false}, {4, 490.0F, 1.9141F}}, + {{pusch_mcs_table::qam64, 14, false, false}, {4, 553.0F, 2.1602F}}, + {{pusch_mcs_table::qam64, 15, false, false}, {4, 616.0F, 2.4063F}}, + {{pusch_mcs_table::qam64, 16, false, false}, {4, 658.0F, 2.5703F}}, + {{pusch_mcs_table::qam64, 17, false, false}, {6, 438.0F, 2.5664F}}, + {{pusch_mcs_table::qam64, 18, false, false}, {6, 466.0F, 2.7305F}}, + {{pusch_mcs_table::qam64, 19, false, false}, {6, 517.0F, 3.0293F}}, + {{pusch_mcs_table::qam64, 20, false, false}, {6, 567.0F, 3.3223F}}, + {{pusch_mcs_table::qam64, 21, false, false}, {6, 616.0F, 3.6094F}}, + {{pusch_mcs_table::qam64, 22, false, false}, {6, 666.0F, 3.9023F}}, + {{pusch_mcs_table::qam64, 23, false, false}, {6, 719.0F, 4.2129F}}, + {{pusch_mcs_table::qam64, 24, false, false}, {6, 772.0F, 4.5234F}}, + {{pusch_mcs_table::qam64, 25, false, false}, {6, 822.0F, 4.8164F}}, + {{pusch_mcs_table::qam64, 26, false, false}, {6, 873.0F, 5.1152F}}, + {{pusch_mcs_table::qam64, 27, false, false}, {6, 910.0F, 5.3320F}}, + {{pusch_mcs_table::qam64, 28, false, false}, {6, 948.0F, 5.5547F}}, + {{pusch_mcs_table::qam64, 29, false, false}, {2, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64, 30, false, false}, {4, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64, 31, false, false}, {6, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam256, 0, false, false}, {2, 120.0F, 0.2344F}}, + {{pusch_mcs_table::qam256, 1, false, false}, {2, 193.0F, 0.3770F}}, + {{pusch_mcs_table::qam256, 2, false, false}, {2, 308.0F, 0.6016F}}, + {{pusch_mcs_table::qam256, 3, false, false}, {2, 449.0F, 0.8770F}}, + {{pusch_mcs_table::qam256, 4, false, false}, {2, 602.0F, 1.1758F}}, + {{pusch_mcs_table::qam256, 5, false, false}, {4, 378.0F, 1.4766F}}, + {{pusch_mcs_table::qam256, 6, false, false}, {4, 434.0F, 1.6953F}}, + {{pusch_mcs_table::qam256, 7, false, false}, {4, 490.0F, 1.9141F}}, + {{pusch_mcs_table::qam256, 8, false, false}, {4, 553.0F, 2.1602F}}, + {{pusch_mcs_table::qam256, 9, false, false}, {4, 616.0F, 2.4063F}}, + {{pusch_mcs_table::qam256, 10, false, false}, {4, 658.0F, 2.5703F}}, + {{pusch_mcs_table::qam256, 11, false, false}, {6, 466.0F, 2.7305F}}, + {{pusch_mcs_table::qam256, 12, false, false}, {6, 517.0F, 3.0293F}}, + {{pusch_mcs_table::qam256, 13, false, false}, {6, 567.0F, 3.3223F}}, + {{pusch_mcs_table::qam256, 14, false, false}, {6, 616.0F, 3.6094F}}, + {{pusch_mcs_table::qam256, 15, false, false}, {6, 666.0F, 3.9023F}}, + {{pusch_mcs_table::qam256, 16, false, false}, {6, 719.0F, 4.2129F}}, + {{pusch_mcs_table::qam256, 17, false, false}, {6, 772.0F, 4.5234F}}, + {{pusch_mcs_table::qam256, 18, false, false}, {6, 822.0F, 4.8164F}}, + {{pusch_mcs_table::qam256, 19, false, false}, {6, 873.0F, 5.1152F}}, + {{pusch_mcs_table::qam256, 20, false, false}, {8, 682.5F, 5.3320F}}, + {{pusch_mcs_table::qam256, 21, false, false}, {8, 711.0F, 5.5547F}}, + {{pusch_mcs_table::qam256, 22, false, false}, {8, 754.0F, 5.8906F}}, + {{pusch_mcs_table::qam256, 23, false, false}, {8, 797.0F, 6.2266F}}, + {{pusch_mcs_table::qam256, 24, false, false}, {8, 841.0F, 6.5703F}}, + {{pusch_mcs_table::qam256, 25, false, false}, {8, 885.0F, 6.9141F}}, + {{pusch_mcs_table::qam256, 26, false, false}, {8, 916.5F, 7.1602F}}, + {{pusch_mcs_table::qam256, 27, false, false}, {8, 948.0F, 7.4063F}}, + {{pusch_mcs_table::qam256, 28, false, false}, {2, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam256, 29, false, false}, {4, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam256, 30, false, false}, {6, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam256, 31, false, false}, {8, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64LowSe, 0, false, false}, {2, 30.0F, 0.0586F}}, + {{pusch_mcs_table::qam64LowSe, 1, false, false}, {2, 40.0F, 0.0781F}}, + {{pusch_mcs_table::qam64LowSe, 2, false, false}, {2, 50.0F, 0.0977F}}, + {{pusch_mcs_table::qam64LowSe, 3, false, false}, {2, 64.0F, 0.1250F}}, + {{pusch_mcs_table::qam64LowSe, 4, false, false}, {2, 78.0F, 0.1523F}}, + {{pusch_mcs_table::qam64LowSe, 5, false, false}, {2, 99.0F, 0.1934F}}, + {{pusch_mcs_table::qam64LowSe, 6, false, false}, {2, 120.0F, 0.2344F}}, + {{pusch_mcs_table::qam64LowSe, 7, false, false}, {2, 157.0F, 0.3066F}}, + {{pusch_mcs_table::qam64LowSe, 8, false, false}, {2, 193.0F, 0.3770F}}, + {{pusch_mcs_table::qam64LowSe, 9, false, false}, {2, 251.0F, 0.4902F}}, + {{pusch_mcs_table::qam64LowSe, 10, false, false}, {2, 308.0F, 0.6016F}}, + {{pusch_mcs_table::qam64LowSe, 11, false, false}, {2, 379.0F, 0.7402F}}, + {{pusch_mcs_table::qam64LowSe, 12, false, false}, {2, 449.0F, 0.8770F}}, + {{pusch_mcs_table::qam64LowSe, 13, false, false}, {2, 526.0F, 1.0273F}}, + {{pusch_mcs_table::qam64LowSe, 14, false, false}, {2, 602.0F, 1.1758F}}, + {{pusch_mcs_table::qam64LowSe, 15, false, false}, {4, 340.0F, 1.3281F}}, + {{pusch_mcs_table::qam64LowSe, 16, false, false}, {4, 378.0F, 1.4766F}}, + {{pusch_mcs_table::qam64LowSe, 17, false, false}, {4, 434.0F, 1.6953F}}, + {{pusch_mcs_table::qam64LowSe, 18, false, false}, {4, 490.0F, 1.9141F}}, + {{pusch_mcs_table::qam64LowSe, 19, false, false}, {4, 553.0F, 2.1602F}}, + {{pusch_mcs_table::qam64LowSe, 20, false, false}, {4, 616.0F, 2.4063F}}, + {{pusch_mcs_table::qam64LowSe, 21, false, false}, {6, 438.0F, 2.5664F}}, + {{pusch_mcs_table::qam64LowSe, 22, false, false}, {6, 466.0F, 2.7305F}}, + {{pusch_mcs_table::qam64LowSe, 23, false, false}, {6, 517.0F, 3.0293F}}, + {{pusch_mcs_table::qam64LowSe, 24, false, false}, {6, 567.0F, 3.3223F}}, + {{pusch_mcs_table::qam64LowSe, 25, false, false}, {6, 616.0F, 3.6094F}}, + {{pusch_mcs_table::qam64LowSe, 26, false, false}, {6, 666.0F, 3.9023F}}, + {{pusch_mcs_table::qam64LowSe, 27, false, false}, {6, 719.0F, 4.2129F}}, + {{pusch_mcs_table::qam64LowSe, 28, false, false}, {6, 772.0F, 4.5234F}}, + {{pusch_mcs_table::qam64LowSe, 29, false, false}, {2, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64LowSe, 30, false, false}, {4, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64LowSe, 31, false, false}, {6, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64, 0, true, false}, {1, 240.0F, 0.2344F}}, + {{pusch_mcs_table::qam64, 1, true, false}, {1, 314.0F, 0.3066F}}, + {{pusch_mcs_table::qam64, 2, true, false}, {2, 193.0F, 0.3770F}}, + {{pusch_mcs_table::qam64, 3, true, false}, {2, 251.0F, 0.4902F}}, + {{pusch_mcs_table::qam64, 4, true, false}, {2, 308.0F, 0.6016F}}, + {{pusch_mcs_table::qam64, 5, true, false}, {2, 379.0F, 0.7402F}}, + {{pusch_mcs_table::qam64, 6, true, false}, {2, 449.0F, 0.8770F}}, + {{pusch_mcs_table::qam64, 7, true, false}, {2, 526.0F, 1.0273F}}, + {{pusch_mcs_table::qam64, 8, true, false}, {2, 602.0F, 1.1758F}}, + {{pusch_mcs_table::qam64, 9, true, false}, {2, 679.0F, 1.3262F}}, + {{pusch_mcs_table::qam64, 10, true, false}, {4, 340.0F, 1.3281F}}, + {{pusch_mcs_table::qam64, 11, true, false}, {4, 378.0F, 1.4766F}}, + {{pusch_mcs_table::qam64, 12, true, false}, {4, 434.0F, 1.6953F}}, + {{pusch_mcs_table::qam64, 13, true, false}, {4, 490.0F, 1.9141F}}, + {{pusch_mcs_table::qam64, 14, true, false}, {4, 553.0F, 2.1602F}}, + {{pusch_mcs_table::qam64, 15, true, false}, {4, 616.0F, 2.4063F}}, + {{pusch_mcs_table::qam64, 16, true, false}, {4, 658.0F, 2.5703F}}, + {{pusch_mcs_table::qam64, 17, true, false}, {6, 466.0F, 2.7305F}}, + {{pusch_mcs_table::qam64, 18, true, false}, {6, 517.0F, 3.0293F}}, + {{pusch_mcs_table::qam64, 19, true, false}, {6, 567.0F, 3.3223F}}, + {{pusch_mcs_table::qam64, 20, true, false}, {6, 616.0F, 3.6094F}}, + {{pusch_mcs_table::qam64, 21, true, false}, {6, 666.0F, 3.9023F}}, + {{pusch_mcs_table::qam64, 22, true, false}, {6, 719.0F, 4.2129F}}, + {{pusch_mcs_table::qam64, 23, true, false}, {6, 772.0F, 4.5234F}}, + {{pusch_mcs_table::qam64, 24, true, false}, {6, 822.0F, 4.8164F}}, + {{pusch_mcs_table::qam64, 25, true, false}, {6, 873.0F, 5.1152F}}, + {{pusch_mcs_table::qam64, 26, true, false}, {6, 910.0F, 5.3320F}}, + {{pusch_mcs_table::qam64, 27, true, false}, {6, 948.0F, 5.5547F}}, + {{pusch_mcs_table::qam64, 28, true, false}, {1, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64, 29, true, false}, {2, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64, 30, true, false}, {4, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64, 31, true, false}, {6, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64LowSe, 0, true, false}, {1, 60.0F, 0.0586F}}, + {{pusch_mcs_table::qam64LowSe, 1, true, false}, {1, 80.0F, 0.0781F}}, + {{pusch_mcs_table::qam64LowSe, 2, true, false}, {1, 100.0F, 0.0977F}}, + {{pusch_mcs_table::qam64LowSe, 3, true, false}, {1, 128.0F, 0.1250F}}, + {{pusch_mcs_table::qam64LowSe, 4, true, false}, {1, 156.0F, 0.1523F}}, + {{pusch_mcs_table::qam64LowSe, 5, true, false}, {1, 198.0F, 0.1934F}}, + {{pusch_mcs_table::qam64LowSe, 6, true, false}, {2, 120.0f, 0.2344F}}, + {{pusch_mcs_table::qam64LowSe, 7, true, false}, {2, 157.0f, 0.3066F}}, + {{pusch_mcs_table::qam64LowSe, 8, true, false}, {2, 193.0f, 0.3770F}}, + {{pusch_mcs_table::qam64LowSe, 9, true, false}, {2, 251.0f, 0.4902F}}, + {{pusch_mcs_table::qam64LowSe, 10, true, false}, {2, 308.0f, 0.6016F}}, + {{pusch_mcs_table::qam64LowSe, 11, true, false}, {2, 379.0f, 0.7402F}}, + {{pusch_mcs_table::qam64LowSe, 12, true, false}, {2, 449.0f, 0.8770F}}, + {{pusch_mcs_table::qam64LowSe, 13, true, false}, {2, 526.0f, 1.0273F}}, + {{pusch_mcs_table::qam64LowSe, 14, true, false}, {2, 602.0f, 1.1758F}}, + {{pusch_mcs_table::qam64LowSe, 15, true, false}, {2, 679.0f, 1.3262F}}, + {{pusch_mcs_table::qam64LowSe, 16, true, false}, {4, 378.0f, 1.4766F}}, + {{pusch_mcs_table::qam64LowSe, 17, true, false}, {4, 434.0f, 1.6953F}}, + {{pusch_mcs_table::qam64LowSe, 18, true, false}, {4, 490.0f, 1.9141F}}, + {{pusch_mcs_table::qam64LowSe, 19, true, false}, {4, 553.0f, 2.1602F}}, + {{pusch_mcs_table::qam64LowSe, 20, true, false}, {4, 616.0f, 2.4063F}}, + {{pusch_mcs_table::qam64LowSe, 21, true, false}, {4, 658.0f, 2.5703F}}, + {{pusch_mcs_table::qam64LowSe, 22, true, false}, {4, 699.0f, 2.7305F}}, + {{pusch_mcs_table::qam64LowSe, 23, true, false}, {4, 772.0f, 3.0156F}}, + {{pusch_mcs_table::qam64LowSe, 24, true, false}, {6, 567.0f, 3.3223F}}, + {{pusch_mcs_table::qam64LowSe, 25, true, false}, {6, 616.0f, 3.6094F}}, + {{pusch_mcs_table::qam64LowSe, 26, true, false}, {6, 666.0f, 3.9023F}}, + {{pusch_mcs_table::qam64LowSe, 27, true, false}, {6, 772.0f, 4.5234F}}, + {{pusch_mcs_table::qam64LowSe, 28, true, false}, {1, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64LowSe, 29, true, false}, {2, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64LowSe, 30, true, false}, {4, 0.0F, 0.0F}}, + {{pusch_mcs_table::qam64LowSe, 31, true, false}, {6, 0.0F, 0.0F}}, }; class pusch_mcs_table_test : public ::testing::TestWithParam @@ -216,14 +210,21 @@ class pusch_mcs_table_test : public ::testing::TestWithParam pusch_mcs_param param = GetParam(); // Table ignores pi2_bpsk_present flag. It indexes with false always. - bool pi2_bpsk_present = std::get<2>(param); - std::get<2>(param) = false; + bool pi2_bpsk_enabled = std::get<3>(param); + std::get<3>(param) = false; + + // Ignore transform precoding when 256-QAM table is selected. + bool use_transform_precoding = std::get<2>(param); + pusch_mcs_table table = std::get<0>(param); + if (use_transform_precoding && (table == pusch_mcs_table::qam256)) { + std::get<2>(param) = false; + } // Return the expected value as pi2_bpsk_present is present. std::tuple expected = pusch_mcs_expected.at(param); // Correct for pi2_bpsk_present. - if (!pi2_bpsk_present && std::get<0>(expected) == 1) { + if (!pi2_bpsk_enabled && std::get<0>(expected) == 1) { std::get<0>(expected) = 2; std::get<1>(expected) /= 2; } @@ -238,12 +239,13 @@ TEST_P(pusch_mcs_table_test, check_combinations) pusch_mcs_param params = GetParam(); // Extract parameters. - pusch_mcs_table table = std::get<0>(params); - sch_mcs_index mcs = std::get<1>(params); - bool pi2_bpsk_enabled = std::get<1>(params); + pusch_mcs_table table = std::get<0>(params); + sch_mcs_index mcs = std::get<1>(params); + bool use_transform_precoding = std::get<2>(params); + bool pi2_bpsk_enabled = std::get<3>(params); // Get number of cyclic shifts. - sch_mcs_description descr = pusch_mcs_get_config(table, mcs, pi2_bpsk_enabled); + sch_mcs_description descr = pusch_mcs_get_config(table, mcs, use_transform_precoding, pi2_bpsk_enabled); std::tuple expected = get_expected(); @@ -259,4 +261,5 @@ INSTANTIATE_TEST_SUITE_P( pusch_mcs_table_test, ::testing::Combine(::testing::Values(pusch_mcs_table::qam64, pusch_mcs_table::qam256, pusch_mcs_table::qam64LowSe), ::testing::Range(0U, 32U), + ::testing::Values(false, true), ::testing::Values(false, true))); From 73e339f0cc6cb824b5db547917d910cc4a8b660f Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 26 Sep 2024 17:16:49 +0200 Subject: [PATCH 148/174] phy: disable TA measurement report for PUCCH Format 1 phy: adjust PHY test --- include/srsran/phy/upper/channel_state_information.h | 5 ++++- lib/phy/upper/channel_processors/pucch_processor_impl.cpp | 3 +++ .../pucch_processor_format1_vectortest.cpp | 3 +-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/srsran/phy/upper/channel_state_information.h b/include/srsran/phy/upper/channel_state_information.h index 14746d520c..fc74770703 100644 --- a/include/srsran/phy/upper/channel_state_information.h +++ b/include/srsran/phy/upper/channel_state_information.h @@ -124,9 +124,12 @@ class channel_state_information /// \return The measured EVM if present, otherwise \c std::nullopt. std::optional get_evm() const { return evm; } - /// \brief Sets the time alignment measurement in PHY time units. + /// Sets the time alignment measurement in PHY time units. void set_time_alignment(const phy_time_unit& time_alignment_) { time_alignment.emplace(time_alignment_); } + /// Resets the time alignment. + void reset_time_alignment() { time_alignment.reset(); } + /// \brief Gets the time alignment. /// /// \return The time aligment measurement if present, otherise \c std::nullopt. diff --git a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp index 9e781115b4..234ad1f5ae 100644 --- a/lib/phy/upper/channel_processors/pucch_processor_impl.cpp +++ b/lib/phy/upper/channel_processors/pucch_processor_impl.cpp @@ -130,6 +130,9 @@ pucch_processor_result pucch_processor_impl::process(const resource_grid_reader& result.message = detection_result.uci_message; result.detection_metric = detection_result.detection_metric; + // Time alignment measurements are unreliable for PUCCH Format 1. + result.csi.reset_time_alignment(); + return result; } diff --git a/tests/unittests/phy/upper/channel_processors/pucch_processor_format1_vectortest.cpp b/tests/unittests/phy/upper/channel_processors/pucch_processor_format1_vectortest.cpp index fd3aa5e46a..8a9220f171 100644 --- a/tests/unittests/phy/upper/channel_processors/pucch_processor_format1_vectortest.cpp +++ b/tests/unittests/phy/upper/channel_processors/pucch_processor_format1_vectortest.cpp @@ -174,8 +174,7 @@ TEST_P(PucchProcessorFormat1Fixture, FromVector) // Check channel state information. // Time alignment shouldn't exceed plus minus 3 us. std::optional time_aligment = result.csi.get_time_alignment(); - ASSERT_TRUE(time_aligment.has_value()); - ASSERT_NEAR(time_aligment.value().to_seconds(), 0, 3e-6); + ASSERT_FALSE(time_aligment.has_value()); // EPRE depends on the number of entries. std::optional epre_dB = result.csi.get_epre_dB(); ASSERT_TRUE(epre_dB.has_value()); From 617853a33a811c181755efdb8b57b4a1f0091983 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Fri, 27 Sep 2024 10:44:12 +0200 Subject: [PATCH 149/174] worker: removed performance message from OFH --- apps/services/worker_manager.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/apps/services/worker_manager.cpp b/apps/services/worker_manager.cpp index 1f072a5f61..af618781b3 100644 --- a/apps/services/worker_manager.cpp +++ b/apps/services/worker_manager.cpp @@ -482,20 +482,7 @@ void worker_manager::create_du_low_executors(bool is_blocking_mode_active, void worker_manager::create_ofh_executors(const worker_manager_config::ru_ofh_config& config) { using namespace execution_config_helper; - - // Maximum number of threads per cell. Implementation defined. The 3 threads are: transmission, reception and - // codification. - static constexpr unsigned MAX_NUM_THREADS_PER_CELL = 3U; - const unsigned nof_cells = config.nof_downlink_antennas.size(); - - unsigned nof_host_threads = std::max(4U, std::max(std::thread::hardware_concurrency(), 4U) - 3U); - - if (nof_host_threads < (nof_cells * MAX_NUM_THREADS_PER_CELL) + 1) { - fmt::print( - "Detected {} threads for Open Fronthaul, but a minimum of {} are needed to achieve a good performance.\n", - nof_host_threads, - (nof_cells * MAX_NUM_THREADS_PER_CELL) + 1); - } + const unsigned nof_cells = config.nof_downlink_antennas.size(); // Timing executor. { From 880ad5ccc17dc571a12ded1204fa5236068c6989 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 24 Sep 2024 11:07:01 +0200 Subject: [PATCH 150/174] cu_cp,ngap: fix log and commandline output on procedure retry/failure --- lib/ngap/procedures/ng_setup_procedure.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ngap/procedures/ng_setup_procedure.cpp b/lib/ngap/procedures/ng_setup_procedure.cpp index b59dadf3f1..e802da3db7 100644 --- a/lib/ngap/procedures/ng_setup_procedure.cpp +++ b/lib/ngap/procedures/ng_setup_procedure.cpp @@ -79,12 +79,12 @@ bool ng_setup_procedure::retry_required() } const asn1::ngap::ng_setup_fail_s& ng_fail = transaction_sink.failure(); - logger.warning("\"{}\" failed. AMF NGAP cause: \"{}\"", name(), get_cause_str(ng_fail->cause)); - fmt::print("\"{}\" failed. AMF NGAP cause: \"{}\"\n", name(), get_cause_str(ng_fail->cause)); if (not ng_fail->time_to_wait_present) { // AMF didn't command a waiting time. logger.warning("\"{}\": Stopping procedure. Cause: AMF did not set any retry waiting time", name()); + logger.warning("\"{}\" failed. AMF NGAP cause: \"{}\"", name(), get_cause_str(ng_fail->cause)); + fmt::print("\"{}\" failed. AMF NGAP cause: \"{}\"\n", name(), get_cause_str(ng_fail->cause)); return false; } if (ng_setup_retry_no++ >= max_setup_retries) { @@ -92,6 +92,8 @@ bool ng_setup_procedure::retry_required() logger.warning("\"{}\": Stopping procedure. Cause: Reached maximum number of NG Setup connection retries ({})", name(), max_setup_retries); + logger.warning("\"{}\" failed. AMF NGAP cause: \"{}\"", name(), get_cause_str(ng_fail->cause)); + fmt::print("\"{}\" failed. AMF NGAP cause: \"{}\"\n", name(), get_cause_str(ng_fail->cause)); return false; } From 83469ab06724f77d2b3d74778cfae7366ce4fb99 Mon Sep 17 00:00:00 2001 From: asaezper Date: Fri, 27 Sep 2024 09:35:49 +0200 Subject: [PATCH 151/174] ci: fix viavi warning/error table --- tests/e2e/tests/steps/stub.py | 8 +++++--- tests/e2e/tests/viavi.py | 16 ++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/tests/e2e/tests/steps/stub.py b/tests/e2e/tests/steps/stub.py index 45800146ac..8fdbeded99 100644 --- a/tests/e2e/tests/steps/stub.py +++ b/tests/e2e/tests/steps/stub.py @@ -696,7 +696,7 @@ def _stop_stub( """ error_msg = "" - warning_count = 0 + error_count = 0 with suppress(grpc.RpcError): stop_info: StopResponse = stub.Stop(UInt32Value(value=timeout)) @@ -723,9 +723,11 @@ def _stop_stub( else: logging.info("%s has stopped", name) - warning_count = stop_info.warning_count + error_count += stop_info.error_count + if warning_as_errors: + error_count += stop_info.warning_count - return error_msg, warning_count + return error_msg, error_count def _get_metrics_msg(stub: RanStub, name: str, fail_if_kos: bool = False) -> str: diff --git a/tests/e2e/tests/viavi.py b/tests/e2e/tests/viavi.py index 3e25768019..ea70555341 100644 --- a/tests/e2e/tests/viavi.py +++ b/tests/e2e/tests/viavi.py @@ -409,7 +409,7 @@ def _test_viavi( logging.info("Folder with Viavi report: %s", report_folder) logging.info("Downloading Viavi report") viavi.download_directory(report_folder, Path(test_log_folder).joinpath("viavi")) - _, gnb_warning_count = _stop_stub( + _, gnb_error_count = _stop_stub( gnb, "GNB", retina_data, gnb_stop_timeout, log_search, test_declaration.warning_as_errors ) check_metrics_criteria( @@ -418,7 +418,7 @@ def _test_viavi( viavi=viavi, metrics_summary=metrics_summary, capsys=capsys, - gnb_warning_count=gnb_warning_count, + gnb_error_count=gnb_error_count, warning_as_errors=test_declaration.warning_as_errors, ) except HTTPError: @@ -434,7 +434,7 @@ def check_metrics_criteria( viavi: Viavi, metrics_summary: Optional[MetricsSummary], capsys: pytest.CaptureFixture[str], - gnb_warning_count: int, + gnb_error_count: int, warning_as_errors: bool, ): """ @@ -469,15 +469,19 @@ def check_metrics_criteria( criteria_nof_ko_aggregate = check_criteria(kpis.nof_ko_aggregate, test_configuration.expected_nof_kos, operator.lt) criteria_result.append( _ViaviResult( - "Number of KOs and/or retrxs", + "Number of KOs & retrxs", test_configuration.expected_nof_kos, kpis.nof_ko_aggregate, criteria_nof_ko_aggregate, ) ) - criteria_nof_warnings = check_criteria(gnb_warning_count, 0, operator.eq) and warning_as_errors - criteria_result.append(_ViaviResult("Number of warnings", 0, gnb_warning_count, criteria_nof_warnings)) + criteria_nof_errors = check_criteria(gnb_error_count, 0, operator.eq) + criteria_result.append( + _ViaviResult( + "Number of errors" + (" & warnings" if warning_as_errors else ""), 0, gnb_error_count, criteria_nof_errors + ) + ) # Check procedure table viavi_failure_manager.print_failures(_OMIT_VIAVI_FAILURE_LIST) From 4ca81d308f40b31c0c20c3d0fc92ac71f112a405 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 25 Sep 2024 13:04:19 +0200 Subject: [PATCH 152/174] sched: use MPMC queue for scheduler events --- .../ue_scheduling/ue_event_manager.cpp | 684 +++++++++--------- .../ue_scheduling/ue_event_manager.h | 18 +- 2 files changed, 369 insertions(+), 333 deletions(-) diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.cpp b/lib/scheduler/ue_scheduling/ue_event_manager.cpp index 73ad3a9f83..35e6e7ea4b 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.cpp +++ b/lib/scheduler/ue_scheduling/ue_event_manager.cpp @@ -103,18 +103,18 @@ class ue_event_manager::ue_dl_buffer_occupancy_manager final : public scheduler_ // Initial capacity for the common and cell event lists, in order to avoid std::vector reallocations. We use the max // nof UEs as a conservative estimate of the expected number of events per slot. -static constexpr size_t INITIAL_COMMON_EVENT_LIST_SIZE = MAX_NOF_DU_UES; -static constexpr size_t INITIAL_CELL_EVENT_LIST_SIZE = MAX_NOF_DU_UES; +static constexpr size_t COMMON_EVENT_LIST_SIZE = MAX_NOF_DU_UES * 2; +static constexpr size_t CELL_EVENT_LIST_SIZE = MAX_NOF_DU_UES * 2; ue_event_manager::ue_event_manager(ue_repository& ue_db_, cell_metrics_handler& metrics_handler_) : ue_db(ue_db_), metrics_handler(metrics_handler_), logger(srslog::fetch_basic_logger("SCHED")), + common_events(COMMON_EVENT_LIST_SIZE), dl_bo_mng(std::make_unique(*this)) { - common_events.reserve(INITIAL_COMMON_EVENT_LIST_SIZE); - for (auto& cell : cell_specific_events) { - cell.reserve(INITIAL_CELL_EVENT_LIST_SIZE); + for (unsigned i = 0; i != MAX_NOF_DU_CELLS; ++i) { + cell_specific_events.emplace_back(CELL_EVENT_LIST_SIZE); } } @@ -129,170 +129,188 @@ void ue_event_manager::handle_ue_creation(ue_config_update_event ev) *du_cells[ev.next_config().pcell_common_cfg().cell_index].cell_harqs}); // Defer UE object addition to ue list to the slot indication handler. - common_events.emplace(INVALID_DU_UE_INDEX, [this, u = std::move(u), ev = std::move(ev)]() mutable { - if (ue_db.contains(u->ue_index)) { - logger.error("ue={} rnti={}: Discarding UE creation. Cause: A UE with the same index already exists", - u->ue_index, - u->crnti); - ev.abort(); - return; - } + if (not common_events.try_push(common_event_t{ + INVALID_DU_UE_INDEX, [this, u = std::move(u), ev = std::move(ev)]() mutable { + if (ue_db.contains(u->ue_index)) { + logger.error("ue={} rnti={}: Discarding UE creation. Cause: A UE with the same index already exists", + u->ue_index, + u->crnti); + ev.abort(); + return; + } - // Insert UE in UE repository. - du_ue_index_t ueidx = u->ue_index; - rnti_t rnti = u->crnti; - du_cell_index_t pcell_index = u->get_pcell().cell_index; - ue_db.add_ue(std::move(u)); + // Insert UE in UE repository. + du_ue_index_t ueidx = u->ue_index; + rnti_t rnti = u->crnti; + du_cell_index_t pcell_index = u->get_pcell().cell_index; + ue_db.add_ue(std::move(u)); - const auto& added_ue = ue_db[ueidx]; - for (unsigned i = 0, e = added_ue.nof_cells(); i != e; ++i) { - // Update UCI scheduler with new UE UCI resources. - du_cells[pcell_index].uci_sched->add_ue(added_ue.get_cell(to_ue_cell_index(i)).cfg()); + const auto& added_ue = ue_db[ueidx]; + for (unsigned i = 0, e = added_ue.nof_cells(); i != e; ++i) { + // Update UCI scheduler with new UE UCI resources. + du_cells[pcell_index].uci_sched->add_ue(added_ue.get_cell(to_ue_cell_index(i)).cfg()); - // Add UE to slice scheduler. - // Note: This action only has effect when UE is created in non-fallback mode. - du_cells[pcell_index].slice_sched->add_ue(ueidx); - } + // Add UE to slice scheduler. + // Note: This action only has effect when UE is created in non-fallback mode. + du_cells[pcell_index].slice_sched->add_ue(ueidx); + } - // Log Event. - du_cells[pcell_index].ev_logger->enqueue(scheduler_event_logger::ue_creation_event{ueidx, rnti, pcell_index}); - }); + // Log Event. + du_cells[pcell_index].ev_logger->enqueue( + scheduler_event_logger::ue_creation_event{ueidx, rnti, pcell_index}); + }})) { + logger.warning("Discarding UE creation. Cause: Event queue is full"); + } } void ue_event_manager::handle_ue_reconfiguration(ue_config_update_event ev) { du_ue_index_t ue_index = ev.get_ue_index(); - common_events.emplace(ue_index, [this, ev = std::move(ev)]() mutable { - const du_ue_index_t ue_idx = ev.get_ue_index(); - if (not ue_db.contains(ue_idx)) { - log_invalid_ue_index(ue_idx, "UE Reconfig Request"); - ev.abort(); - return; - } - auto& u = ue_db[ue_idx]; - - // If a UE carrier has been removed, remove the UE from the respective slice scheduler. - // Update UCI scheduler with cell changes. - for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { - auto& ue_cc = u.get_cell(to_ue_cell_index(i)); - if (not ev.next_config().contains(ue_cc.cell_index)) { - // UE carrier is being removed. - // Update UE UCI resources in UCI scheduler. - du_cells[ue_cc.cell_index].uci_sched->rem_ue(ue_cc.cfg()); - // Schedule removal of UE in slice scheduler. - du_cells[ue_cc.cell_index].slice_sched->rem_ue(ue_idx); - } else { - // UE carrier is being reconfigured. - du_cells[ue_cc.cell_index].uci_sched->reconf_ue(ev.next_config().ue_cell_cfg(ue_cc.cell_index), ue_cc.cfg()); - } - } - for (unsigned i = 0, e = ev.next_config().nof_cells(); i != e; ++i) { - const auto& new_ue_cc_cfg = ev.next_config().ue_cell_cfg(to_ue_cell_index(i)); - auto* ue_cc = u.find_cell(new_ue_cc_cfg.cell_cfg_common.cell_index); - if (ue_cc == nullptr) { - // New UE carrier is being added. - du_cells[new_ue_cc_cfg.cell_cfg_common.cell_index].uci_sched->add_ue(new_ue_cc_cfg); - } - } - - // Configure existing UE. - ue_db[ue_idx].handle_reconfiguration_request(ue_reconf_command{ev.next_config()}); - - // Update slice scheduler. - for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { - const auto& ue_cc = u.get_cell(to_ue_cell_index(i)); - // Reconfigure UE in slice scheduler. - du_cells[ue_cc.cell_index].slice_sched->reconf_ue(u.ue_index); - } - - // Log event. - du_cells[u.get_pcell().cell_index].ev_logger->enqueue(scheduler_event_logger::ue_reconf_event{ue_idx, u.crnti}); - }); + if (not common_events.try_push( + common_event_t{ue_index, [this, ev = std::move(ev)]() mutable { + const du_ue_index_t ue_idx = ev.get_ue_index(); + if (not ue_db.contains(ue_idx)) { + log_invalid_ue_index(ue_idx, "UE Reconfig Request"); + ev.abort(); + return; + } + auto& u = ue_db[ue_idx]; + + // If a UE carrier has been removed, remove the UE from the respective slice scheduler. + // Update UCI scheduler with cell changes. + for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { + auto& ue_cc = u.get_cell(to_ue_cell_index(i)); + if (not ev.next_config().contains(ue_cc.cell_index)) { + // UE carrier is being removed. + // Update UE UCI resources in UCI scheduler. + du_cells[ue_cc.cell_index].uci_sched->rem_ue(ue_cc.cfg()); + // Schedule removal of UE in slice scheduler. + du_cells[ue_cc.cell_index].slice_sched->rem_ue(ue_idx); + } else { + // UE carrier is being reconfigured. + du_cells[ue_cc.cell_index].uci_sched->reconf_ue( + ev.next_config().ue_cell_cfg(ue_cc.cell_index), ue_cc.cfg()); + } + } + for (unsigned i = 0, e = ev.next_config().nof_cells(); i != e; ++i) { + const auto& new_ue_cc_cfg = ev.next_config().ue_cell_cfg(to_ue_cell_index(i)); + auto* ue_cc = u.find_cell(new_ue_cc_cfg.cell_cfg_common.cell_index); + if (ue_cc == nullptr) { + // New UE carrier is being added. + du_cells[new_ue_cc_cfg.cell_cfg_common.cell_index].uci_sched->add_ue(new_ue_cc_cfg); + } + } + + // Configure existing UE. + ue_db[ue_idx].handle_reconfiguration_request(ue_reconf_command{ev.next_config()}); + + // Update slice scheduler. + for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { + const auto& ue_cc = u.get_cell(to_ue_cell_index(i)); + // Reconfigure UE in slice scheduler. + du_cells[ue_cc.cell_index].slice_sched->reconf_ue(u.ue_index); + } + + // Log event. + du_cells[u.get_pcell().cell_index].ev_logger->enqueue( + scheduler_event_logger::ue_reconf_event{ue_idx, u.crnti}); + }})) { + logger.warning("Discarding UE reconfiguration. Cause: Event queue is full"); + } } void ue_event_manager::handle_ue_deletion(ue_config_delete_event ev) { const du_ue_index_t ue_index = ev.ue_index(); - common_events.emplace(ue_index, [this, ev = std::move(ev)]() mutable { - const du_ue_index_t ue_idx = ev.ue_index(); - if (not ue_db.contains(ue_idx)) { - logger.warning("Received request to delete ue={} that does not exist", ue_idx); - return; - } - const auto& u = ue_db[ue_idx]; - const rnti_t rnti = u.crnti; - du_cell_index_t pcell_idx = u.get_pcell().cell_index; - - for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { - // Update UCI scheduling by removing existing UE UCI resources. - du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].uci_sched->rem_ue(u.get_pcell().cfg()); - // Schedule removal of UE from slice scheduler. - du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].slice_sched->rem_ue(ue_idx); - } + if (not common_events.try_push(common_event_t{ + ue_index, [this, ev = std::move(ev)]() mutable { + const du_ue_index_t ue_idx = ev.ue_index(); + if (not ue_db.contains(ue_idx)) { + logger.warning("Received request to delete ue={} that does not exist", ue_idx); + return; + } + const auto& u = ue_db[ue_idx]; + const rnti_t rnti = u.crnti; + du_cell_index_t pcell_idx = u.get_pcell().cell_index; + + for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { + // Update UCI scheduling by removing existing UE UCI resources. + du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].uci_sched->rem_ue(u.get_pcell().cfg()); + // Schedule removal of UE from slice scheduler. + du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].slice_sched->rem_ue(ue_idx); + } - // Schedule UE removal from repository. - ue_db.schedule_ue_rem(std::move(ev)); + // Schedule UE removal from repository. + ue_db.schedule_ue_rem(std::move(ev)); - // Log UE removal event. - du_cells[pcell_idx].ev_logger->enqueue(sched_ue_delete_message{ue_idx, rnti}); - }); + // Log UE removal event. + du_cells[pcell_idx].ev_logger->enqueue(sched_ue_delete_message{ue_idx, rnti}); + }})) { + logger.warning("Discarding UE deletion. Cause: Event queue is full"); + } } void ue_event_manager::handle_ue_config_applied(du_ue_index_t ue_idx) { - common_events.emplace(ue_idx, [this, ue_idx]() { - if (not ue_db.contains(ue_idx)) { - logger.warning("Received config application confirmation for ue={} that does not exist", ue_idx); - return; - } - ue& u = ue_db[ue_idx]; - auto& pcell = du_cells[u.get_pcell().cell_index]; + if (not common_events.try_push(common_event_t{ + ue_idx, [this, ue_idx]() { + if (not ue_db.contains(ue_idx)) { + logger.warning("Received config application confirmation for ue={} that does not exist", ue_idx); + return; + } + ue& u = ue_db[ue_idx]; + auto& pcell = du_cells[u.get_pcell().cell_index]; - // Log UE config applied event. - pcell.ev_logger->enqueue(scheduler_event_logger::ue_cfg_applied_event{ue_idx, u.crnti}); + // Log UE config applied event. + pcell.ev_logger->enqueue(scheduler_event_logger::ue_cfg_applied_event{ue_idx, u.crnti}); - // Remove UE from fallback mode. - u.get_pcell().set_fallback_state(false); + // Remove UE from fallback mode. + u.get_pcell().set_fallback_state(false); - // Add UE to slice scheduler, once it leaves fallback mode. - pcell.slice_sched->config_applied(ue_idx); - }); + // Add UE to slice scheduler, once it leaves fallback mode. + pcell.slice_sched->config_applied(ue_idx); + }})) { + logger.warning("Discarding UE config applied. Cause: Event queue is full"); + } } void ue_event_manager::handle_ul_bsr_indication(const ul_bsr_indication_message& bsr_ind) { srsran_sanity_check(cell_exists(bsr_ind.cell_index), "Invalid cell index"); - common_events.emplace(bsr_ind.ue_index, [this, bsr_ind]() { - if (not ue_db.contains(bsr_ind.ue_index)) { - log_invalid_ue_index(bsr_ind.ue_index, "BSR"); - return; - } - auto& u = ue_db[bsr_ind.ue_index]; - du_cell_index_t pcell_idx = u.get_pcell().cell_index; - - // Handle event. - u.handle_bsr_indication(bsr_ind); - - if (u.get_pcell().is_in_fallback_mode()) { - // Signal SRB fallback scheduler with the new SRB0/SRB1 buffer state. - du_cells[pcell_idx].fallback_sched->handle_ul_bsr_indication(bsr_ind.ue_index, bsr_ind); - } - - // Log event. - if (du_cells[pcell_idx].ev_logger->enabled()) { - scheduler_event_logger::bsr_event event{}; - event.ue_index = bsr_ind.ue_index; - event.rnti = bsr_ind.crnti; - event.type = bsr_ind.type; - event.reported_lcgs = bsr_ind.reported_lcgs; - event.tot_ul_pending_bytes = units::bytes{u.pending_ul_newtx_bytes()}; - du_cells[pcell_idx].ev_logger->enqueue(event); - } - - // Notify metrics handler. - metrics_handler.handle_ul_bsr_indication(bsr_ind); - }); + if (not common_events.try_push( + common_event_t{bsr_ind.ue_index, [this, bsr_ind]() { + if (not ue_db.contains(bsr_ind.ue_index)) { + log_invalid_ue_index(bsr_ind.ue_index, "BSR"); + return; + } + auto& u = ue_db[bsr_ind.ue_index]; + du_cell_index_t pcell_idx = u.get_pcell().cell_index; + + // Handle event. + u.handle_bsr_indication(bsr_ind); + + if (u.get_pcell().is_in_fallback_mode()) { + // Signal SRB fallback scheduler with the new SRB0/SRB1 buffer state. + du_cells[pcell_idx].fallback_sched->handle_ul_bsr_indication(bsr_ind.ue_index, bsr_ind); + } + + // Log event. + if (du_cells[pcell_idx].ev_logger->enabled()) { + scheduler_event_logger::bsr_event event{}; + event.ue_index = bsr_ind.ue_index; + event.rnti = bsr_ind.crnti; + event.type = bsr_ind.type; + event.reported_lcgs = bsr_ind.reported_lcgs; + event.tot_ul_pending_bytes = units::bytes{u.pending_ul_newtx_bytes()}; + du_cells[pcell_idx].ev_logger->enqueue(event); + } + + // Notify metrics handler. + metrics_handler.handle_ul_bsr_indication(bsr_ind); + }})) { + logger.warning("Discarding UE BSR. Cause: Event queue is full"); + } } void ue_event_manager::handle_ul_phr_indication(const ul_phr_indication_message& phr_ind) @@ -300,25 +318,27 @@ void ue_event_manager::handle_ul_phr_indication(const ul_phr_indication_message& for (const cell_ph_report& cell_phr : phr_ind.phr.get_phr()) { srsran_sanity_check(cell_exists(cell_phr.serv_cell_id), "Invalid serving cell index={}", cell_phr.serv_cell_id); - cell_specific_events[cell_phr.serv_cell_id].emplace( - phr_ind.ue_index, - [this, cell_phr, phr_ind](ue_cell& ue_cc) { - ue_cc.channel_state_manager().handle_phr(cell_phr); - - // Log event. - scheduler_event_logger::phr_event event{}; - event.ue_index = phr_ind.ue_index; - event.rnti = phr_ind.rnti; - event.cell_index = cell_phr.serv_cell_id; - event.ph = cell_phr.ph; - event.p_cmax = cell_phr.p_cmax; - du_cells[cell_phr.serv_cell_id].ev_logger->enqueue(event); - - // Notify metrics handler. - metrics_handler.handle_ul_phr_indication(phr_ind); - }, - "UL PHR", - true); + if (not cell_specific_events[cell_phr.serv_cell_id].try_push( + cell_event_t{phr_ind.ue_index, + [this, cell_phr, phr_ind](ue_cell& ue_cc) { + ue_cc.channel_state_manager().handle_phr(cell_phr); + + // Log event. + scheduler_event_logger::phr_event event{}; + event.ue_index = phr_ind.ue_index; + event.rnti = phr_ind.rnti; + event.cell_index = cell_phr.serv_cell_id; + event.ph = cell_phr.ph; + event.p_cmax = cell_phr.p_cmax; + du_cells[cell_phr.serv_cell_id].ev_logger->enqueue(event); + + // Notify metrics handler. + metrics_handler.handle_ul_phr_indication(phr_ind); + }, + "UL PHR", + true})) { + logger.warning("Discarding PHR. Cause: Event queue is full"); + } } } @@ -326,30 +346,32 @@ void ue_event_manager::handle_crc_indication(const ul_crc_indication& crc_ind) { srsran_assert(cell_exists(crc_ind.cell_index), "Invalid cell index"); for (unsigned i = 0, e = crc_ind.crcs.size(); i != e; ++i) { - cell_specific_events[crc_ind.cell_index].emplace( - crc_ind.crcs[i].ue_index, - [this, sl_rx = crc_ind.sl_rx, crc = crc_ind.crcs[i]](ue_cell& ue_cc) { - const int tbs = ue_cc.handle_crc_pdu(sl_rx, crc); - if (tbs < 0) { - return; - } - - // Process Timing Advance Offset. - if (crc.tb_crc_success and crc.time_advance_offset.has_value() and crc.ul_sinr_dB.has_value()) { - ue_db[ue_cc.ue_index].handle_ul_n_ta_update_indication( - ue_cc.cell_index, crc.ul_sinr_dB.value(), crc.time_advance_offset.value()); - } - - // Log event. - du_cells[ue_cc.cell_index].ev_logger->enqueue(scheduler_event_logger::crc_event{ - crc.ue_index, crc.rnti, ue_cc.cell_index, sl_rx, crc.harq_id, crc.tb_crc_success, crc.ul_sinr_dB}); - - // Notify metrics handler. - metrics_handler.handle_crc_indication(crc, units::bytes{(unsigned)tbs}); - metrics_handler.handle_ul_delay(crc.ue_index, last_sl - sl_rx); - }, - "CRC", - true); + if (not cell_specific_events[crc_ind.cell_index].try_push(cell_event_t{ + crc_ind.crcs[i].ue_index, + [this, sl_rx = crc_ind.sl_rx, crc = crc_ind.crcs[i]](ue_cell& ue_cc) { + const int tbs = ue_cc.handle_crc_pdu(sl_rx, crc); + if (tbs < 0) { + return; + } + + // Process Timing Advance Offset. + if (crc.tb_crc_success and crc.time_advance_offset.has_value() and crc.ul_sinr_dB.has_value()) { + ue_db[ue_cc.ue_index].handle_ul_n_ta_update_indication( + ue_cc.cell_index, crc.ul_sinr_dB.value(), crc.time_advance_offset.value()); + } + + // Log event. + du_cells[ue_cc.cell_index].ev_logger->enqueue(scheduler_event_logger::crc_event{ + crc.ue_index, crc.rnti, ue_cc.cell_index, sl_rx, crc.harq_id, crc.tb_crc_success, crc.ul_sinr_dB}); + + // Notify metrics handler. + metrics_handler.handle_crc_indication(crc, units::bytes{(unsigned)tbs}); + metrics_handler.handle_ul_delay(crc.ue_index, last_sl - sl_rx); + }, + "CRC", + true})) { + logger.warning("Discarding CRC. Cause: Event queue is full"); + } } } @@ -396,106 +418,113 @@ void ue_event_manager::handle_uci_indication(const uci_indication& ind) for (unsigned i = 0, e = ind.ucis.size(); i != e; ++i) { const uci_indication::uci_pdu& uci = ind.ucis[i]; - cell_specific_events[ind.cell_index].emplace( - uci.ue_index, - [this, uci_sl = ind.slot_rx, uci_pdu = uci](ue_cell& ue_cc) { - if (const auto* pucch_f0f1 = std::get_if(&uci_pdu.pdu)) { - // Process DL HARQ ACKs. - if (not pucch_f0f1->harqs.empty()) { - handle_harq_ind(ue_cc, uci_sl, pucch_f0f1->harqs, pucch_f0f1->ul_sinr_dB); - } - - // Process SRs. - if (pucch_f0f1->sr_detected) { - // Handle SR indication. - ue_db[ue_cc.ue_index].handle_sr_indication(); - du_cells[ue_cc.cell_index].fallback_sched->handle_sr_indication(ue_cc.ue_index); - - // Log SR event. - du_cells[ue_cc.cell_index].ev_logger->enqueue( - scheduler_event_logger::sr_event{ue_cc.ue_index, ue_cc.rnti()}); - } - - const bool is_uci_valid = not pucch_f0f1->harqs.empty() or pucch_f0f1->sr_detected; - // Process Timing Advance Offset. - if (is_uci_valid and pucch_f0f1->time_advance_offset.has_value() and pucch_f0f1->ul_sinr_dB.has_value()) { - ue_db[ue_cc.ue_index].handle_ul_n_ta_update_indication( - ue_cc.cell_index, pucch_f0f1->ul_sinr_dB.value(), pucch_f0f1->time_advance_offset.value()); - } - } else if (const auto* pusch_pdu = std::get_if(&uci_pdu.pdu)) { - // Process DL HARQ ACKs. - if (not pusch_pdu->harqs.empty()) { - handle_harq_ind(ue_cc, uci_sl, pusch_pdu->harqs, std::nullopt); - } - - // Process CSI. - if (pusch_pdu->csi.has_value()) { - handle_csi(ue_cc, *pusch_pdu->csi); - } - } else if (const auto* pucch_f2f3f4 = - std::get_if(&uci_pdu.pdu)) { - // Process DL HARQ ACKs. - if (not pucch_f2f3f4->harqs.empty()) { - handle_harq_ind(ue_cc, uci_sl, pucch_f2f3f4->harqs, pucch_f2f3f4->ul_sinr_dB); - } - - // Process SRs. - const size_t sr_bit_position_with_1_sr_bit = 0; - if (not pucch_f2f3f4->sr_info.empty() and pucch_f2f3f4->sr_info.test(sr_bit_position_with_1_sr_bit)) { - // Handle SR indication. - ue_db[ue_cc.ue_index].handle_sr_indication(); - - // Log SR event. - du_cells[ue_cc.cell_index].ev_logger->enqueue( - scheduler_event_logger::sr_event{ue_cc.ue_index, ue_cc.rnti()}); - } - - // Process CSI. - if (pucch_f2f3f4->csi.has_value()) { - handle_csi(ue_cc, *pucch_f2f3f4->csi); - } - - const bool is_uci_valid = - not pucch_f2f3f4->harqs.empty() or - (not pucch_f2f3f4->sr_info.empty() and pucch_f2f3f4->sr_info.test(sr_bit_position_with_1_sr_bit)) or - pucch_f2f3f4->csi.has_value(); - // Process Timing Advance Offset. - if (is_uci_valid and pucch_f2f3f4->time_advance_offset.has_value() and - pucch_f2f3f4->ul_sinr_dB.has_value()) { - ue_db[ue_cc.ue_index].handle_ul_n_ta_update_indication( - ue_cc.cell_index, pucch_f2f3f4->ul_sinr_dB.value(), pucch_f2f3f4->time_advance_offset.value()); - } - } - - // Report the UCI PDU to the metrics handler. - metrics_handler.handle_uci_pdu_indication(uci_pdu); - }, - "UCI", - // Note: We do not warn if the UE is not found, because there is this transient period when the UE - // is about to receive and process the RRC Release, but it is still sending CSI or SR in the PUCCH. If we stop - // the PUCCH scheduling for the UE about to be released, we could risk interference between UEs in the PUCCH. - false); + if (not cell_specific_events[ind.cell_index].try_push(cell_event_t{ + uci.ue_index, + [this, uci_sl = ind.slot_rx, uci_pdu = uci](ue_cell& ue_cc) { + if (const auto* pucch_f0f1 = std::get_if(&uci_pdu.pdu)) { + // Process DL HARQ ACKs. + if (not pucch_f0f1->harqs.empty()) { + handle_harq_ind(ue_cc, uci_sl, pucch_f0f1->harqs, pucch_f0f1->ul_sinr_dB); + } + + // Process SRs. + if (pucch_f0f1->sr_detected) { + // Handle SR indication. + ue_db[ue_cc.ue_index].handle_sr_indication(); + du_cells[ue_cc.cell_index].fallback_sched->handle_sr_indication(ue_cc.ue_index); + + // Log SR event. + du_cells[ue_cc.cell_index].ev_logger->enqueue( + scheduler_event_logger::sr_event{ue_cc.ue_index, ue_cc.rnti()}); + } + + const bool is_uci_valid = not pucch_f0f1->harqs.empty() or pucch_f0f1->sr_detected; + // Process Timing Advance Offset. + if (is_uci_valid and pucch_f0f1->time_advance_offset.has_value() and + pucch_f0f1->ul_sinr_dB.has_value()) { + ue_db[ue_cc.ue_index].handle_ul_n_ta_update_indication( + ue_cc.cell_index, pucch_f0f1->ul_sinr_dB.value(), pucch_f0f1->time_advance_offset.value()); + } + } else if (const auto* pusch_pdu = std::get_if(&uci_pdu.pdu)) { + // Process DL HARQ ACKs. + if (not pusch_pdu->harqs.empty()) { + handle_harq_ind(ue_cc, uci_sl, pusch_pdu->harqs, std::nullopt); + } + + // Process CSI. + if (pusch_pdu->csi.has_value()) { + handle_csi(ue_cc, *pusch_pdu->csi); + } + } else if (const auto* pucch_f2f3f4 = + std::get_if(&uci_pdu.pdu)) { + // Process DL HARQ ACKs. + if (not pucch_f2f3f4->harqs.empty()) { + handle_harq_ind(ue_cc, uci_sl, pucch_f2f3f4->harqs, pucch_f2f3f4->ul_sinr_dB); + } + + // Process SRs. + const size_t sr_bit_position_with_1_sr_bit = 0; + if (not pucch_f2f3f4->sr_info.empty() and pucch_f2f3f4->sr_info.test(sr_bit_position_with_1_sr_bit)) { + // Handle SR indication. + ue_db[ue_cc.ue_index].handle_sr_indication(); + + // Log SR event. + du_cells[ue_cc.cell_index].ev_logger->enqueue( + scheduler_event_logger::sr_event{ue_cc.ue_index, ue_cc.rnti()}); + } + + // Process CSI. + if (pucch_f2f3f4->csi.has_value()) { + handle_csi(ue_cc, *pucch_f2f3f4->csi); + } + + const bool is_uci_valid = + not pucch_f2f3f4->harqs.empty() or + (not pucch_f2f3f4->sr_info.empty() and pucch_f2f3f4->sr_info.test(sr_bit_position_with_1_sr_bit)) or + pucch_f2f3f4->csi.has_value(); + // Process Timing Advance Offset. + if (is_uci_valid and pucch_f2f3f4->time_advance_offset.has_value() and + pucch_f2f3f4->ul_sinr_dB.has_value()) { + ue_db[ue_cc.ue_index].handle_ul_n_ta_update_indication( + ue_cc.cell_index, pucch_f2f3f4->ul_sinr_dB.value(), pucch_f2f3f4->time_advance_offset.value()); + } + } + + // Report the UCI PDU to the metrics handler. + metrics_handler.handle_uci_pdu_indication(uci_pdu); + }, + "UCI", + // Note: We do not warn if the UE is not found, because there is this transient period when the UE + // is about to receive and process the RRC Release, but it is still sending CSI or SR in the PUCCH. If we + // stop the PUCCH scheduling for the UE about to be released, we could risk interference between UEs in the + // PUCCH. + false})) { + logger.warning("UCI discarded. Cause: Event queue is full"); + } } } void ue_event_manager::handle_dl_mac_ce_indication(const dl_mac_ce_indication& ce) { - common_events.emplace(ce.ue_index, [this, ce]() { - if (not ue_db.contains(ce.ue_index)) { - log_invalid_ue_index(ce.ue_index, "DL MAC CE"); - return; - } - auto& u = ue_db[ce.ue_index]; - u.handle_dl_mac_ce_indication(ce); + if (not common_events.try_push(common_event_t{ + ce.ue_index, [this, ce]() { + if (not ue_db.contains(ce.ue_index)) { + log_invalid_ue_index(ce.ue_index, "DL MAC CE"); + return; + } + auto& u = ue_db[ce.ue_index]; + u.handle_dl_mac_ce_indication(ce); - // Notify SRB fallback scheduler upon receiving ConRes CE indication. - if (ce.ce_lcid == lcid_dl_sch_t::UE_CON_RES_ID) { - du_cells[ue_db[ce.ue_index].get_pcell().cell_index].fallback_sched->handle_conres_indication(ce.ue_index); - } + // Notify SRB fallback scheduler upon receiving ConRes CE indication. + if (ce.ce_lcid == lcid_dl_sch_t::UE_CON_RES_ID) { + du_cells[ue_db[ce.ue_index].get_pcell().cell_index].fallback_sched->handle_conres_indication(ce.ue_index); + } - // Log event. - du_cells[u.get_pcell().cell_index].ev_logger->enqueue(ce); - }); + // Log event. + du_cells[u.get_pcell().cell_index].ev_logger->enqueue(ce); + }})) { + logger.warning("DL MAC CE discarded. Cause: Event queue is full"); + } } void ue_event_manager::handle_dl_buffer_state_indication(const dl_buffer_state_indication_message& bs) @@ -575,49 +604,54 @@ void ue_event_manager::handle_error_indication(slot_point du_cell_index_t cell_index, scheduler_slot_handler::error_outcome event) { - common_events.emplace(INVALID_DU_UE_INDEX, [this, sl_tx, cell_index, event]() { - // Handle Error Indication. - - const cell_slot_resource_allocator* prev_slot_result = du_cells[cell_index].res_grid->get_history(sl_tx); - if (prev_slot_result == nullptr) { - logger.warning("cell={}, slot={}: Discarding error indication. Cause: Scheduler results associated with the slot " - "of the error indication have already been erased", - cell_index, - sl_tx); - return; - } + if (not common_events.try_push(common_event_t{ + INVALID_DU_UE_INDEX, [this, sl_tx, cell_index, event]() { + // Handle Error Indication. + + const cell_slot_resource_allocator* prev_slot_result = du_cells[cell_index].res_grid->get_history(sl_tx); + if (prev_slot_result == nullptr) { + logger.warning( + "cell={}, slot={}: Discarding error indication. Cause: Scheduler results associated with the slot " + "of the error indication have already been erased", + cell_index, + sl_tx); + return; + } - // In case DL PDCCHs were skipped, there will be the following consequences: - // - The UE will not decode the PDSCH and will not send the respective UCI. - // - The UE won't update the HARQ NDI, if new HARQ TB. - // - The UCI indication coming later from the lower layers will likely contain a HARQ-ACK=DTX. - // In case UL PDCCHs were skipped, there will be the following consequences: - // - The UE will not decode the PUSCH. - // - The UE won't update the HARQ NDI, if new HARQ TB. - // - The CRC indication coming from the lower layers will likely be CRC=KO. - // - Any UCI in the respective PUSCH will be likely reported as HARQ-ACK=DTX. - // In neither of the cases, the HARQs will timeout, because we did not lose the UCI/CRC indications in the lower - // layers. We do not need to cancel associated PUSCH grant (in UL PDCCH case) because it is important that - // the PUSCH "new_data" flag reaches the lower layers, telling them whether the UL HARQ buffer needs to be reset or - // not. Cancelling HARQ retransmissions is dangerous as it increases the chances of NDI ambiguity. - - // In case of PDSCH grants being discarded, there will be the following consequences: - // - If the PDCCH was not discarded,the UE will fail to decode the PDSCH and will send an HARQ-ACK=NACK. The - // scheduler will retransmit the respective DL HARQ. No actions required. - - // In case of PUCCH and PUSCH grants being discarded. - if (event.pusch_and_pucch_discarded) { - handle_discarded_pusch(*prev_slot_result, ue_db); - - handle_discarded_pucch(*prev_slot_result, ue_db); - } + // In case DL PDCCHs were skipped, there will be the following consequences: + // - The UE will not decode the PDSCH and will not send the respective UCI. + // - The UE won't update the HARQ NDI, if new HARQ TB. + // - The UCI indication coming later from the lower layers will likely contain a HARQ-ACK=DTX. + // In case UL PDCCHs were skipped, there will be the following consequences: + // - The UE will not decode the PUSCH. + // - The UE won't update the HARQ NDI, if new HARQ TB. + // - The CRC indication coming from the lower layers will likely be CRC=KO. + // - Any UCI in the respective PUSCH will be likely reported as HARQ-ACK=DTX. + // In neither of the cases, the HARQs will timeout, because we did not lose the UCI/CRC indications in the + // lower layers. We do not need to cancel associated PUSCH grant (in UL PDCCH case) because it is important + // that the PUSCH "new_data" flag reaches the lower layers, telling them whether the UL HARQ buffer needs to + // be reset or not. Cancelling HARQ retransmissions is dangerous as it increases the chances of NDI + // ambiguity. + + // In case of PDSCH grants being discarded, there will be the following consequences: + // - If the PDCCH was not discarded,the UE will fail to decode the PDSCH and will send an HARQ-ACK=NACK. The + // scheduler will retransmit the respective DL HARQ. No actions required. + + // In case of PUCCH and PUSCH grants being discarded. + if (event.pusch_and_pucch_discarded) { + handle_discarded_pusch(*prev_slot_result, ue_db); + + handle_discarded_pucch(*prev_slot_result, ue_db); + } - // Log event. - du_cells[cell_index].ev_logger->enqueue(scheduler_event_logger::error_indication_event{sl_tx, event}); + // Log event. + du_cells[cell_index].ev_logger->enqueue(scheduler_event_logger::error_indication_event{sl_tx, event}); - // Report metrics. - metrics_handler.handle_error_indication(); - }); + // Report metrics. + metrics_handler.handle_error_indication(); + }})) { + logger.warning("Discarding error indication. Cause: Event queue is full"); + } } void ue_event_manager::process_common(slot_point sl, du_cell_index_t cell_index) @@ -625,32 +659,24 @@ void ue_event_manager::process_common(slot_point sl, du_cell_index_t cell_index) bool new_slot_detected = last_sl != sl; if (new_slot_detected) { // Pop pending common events. - common_events.slot_indication(); last_sl = sl; } // Process events for UEs whose PCell matches cell_index argument. - span events_to_process = common_events.get_events(); - for (common_event_t& ev : events_to_process) { - if (ev.callback.is_empty()) { - // Event already processed. - continue; - } + common_event_t ev{MAX_NOF_DU_UES, []() {}}; + while (common_events.try_pop(ev)) { if (ev.ue_index == MAX_NOF_DU_UES) { // The UE is being created. ev.callback(); - ev.callback = {}; } else { if (not ue_db.contains(ev.ue_index)) { // Can't find UE. Log error. log_invalid_ue_index(ev.ue_index); - ev.callback = {}; continue; } if (ue_db[ev.ue_index].get_pcell().cell_index == cell_index) { // If we are currently processing PCell. ev.callback(); - ev.callback = {}; } } } @@ -663,9 +689,9 @@ void ue_event_manager::process_common(slot_point sl, du_cell_index_t cell_index) void ue_event_manager::process_cell_specific(du_cell_index_t cell_index) { // Pop and process pending cell-specific events. - cell_specific_events[cell_index].slot_indication(); - auto events = cell_specific_events[cell_index].get_events(); - for (cell_event_t& ev : events) { + auto& cell_events = cell_specific_events[cell_index]; + cell_event_t ev{INVALID_DU_UE_INDEX, [](ue_cell&) {}, "invalid", true}; + while (cell_events.try_pop(ev)) { if (not ue_db.contains(ev.ue_index)) { log_invalid_ue_index(ev.ue_index, ev.event_name, ev.warn_if_ignored); continue; diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.h b/lib/scheduler/ue_scheduling/ue_event_manager.h index 0ef16ebd4f..1d637a69bf 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.h +++ b/lib/scheduler/ue_scheduling/ue_event_manager.h @@ -15,6 +15,8 @@ #include "../support/slot_event_list.h" #include "ue.h" #include "ue_fallback_scheduler.h" +#include "srsran/adt/concurrent_queue.h" +#include "srsran/adt/mpmc_queue.h" #include "srsran/adt/unique_function.h" #include "srsran/ran/du_types.h" @@ -34,7 +36,7 @@ class ue_event_manager final : public sched_ue_configuration_handler, { public: ue_event_manager(ue_repository& ue_db, cell_metrics_handler& metrics_handler); - ~ue_event_manager(); + ~ue_event_manager() override; void add_cell(cell_resource_allocator& cell_res_grid, cell_harq_manager& cell_harqs, @@ -93,6 +95,13 @@ class ue_event_manager final : public sched_ue_configuration_handler, } }; + using common_event_queue = concurrent_queue; + using cell_event_queue = concurrent_queue; + void process_common(slot_point sl, du_cell_index_t cell_index); void process_cell_specific(du_cell_index_t cell_index); bool cell_exists(du_cell_index_t cell_index) const; @@ -133,12 +142,13 @@ class ue_event_manager final : public sched_ue_configuration_handler, std::array du_cells{}; /// Pending Events list per cell. - std::array, MAX_NOF_DU_CELLS> cell_specific_events; + static_vector cell_specific_events; /// Pending Events list common to all cells. We use this list for events that require synchronization across /// UE carriers when CA is enabled (e.g. SR, BSR, reconfig). - slot_event_list common_events; - slot_point last_sl; + common_event_queue common_events; + + slot_point last_sl; std::unique_ptr dl_bo_mng; }; From 6f338988712877f408d0187c487d93bfd31c102e Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 26 Sep 2024 15:30:40 +0200 Subject: [PATCH 153/174] sched: remove slot_event_list from ue_event_manager --- .../ue_scheduling/ue_event_manager.cpp | 39 ++++++++++--------- .../ue_scheduling/ue_event_manager.h | 1 - 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.cpp b/lib/scheduler/ue_scheduling/ue_event_manager.cpp index 35e6e7ea4b..c4db0d9782 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.cpp +++ b/lib/scheduler/ue_scheduling/ue_event_manager.cpp @@ -27,9 +27,8 @@ class ue_event_manager::ue_dl_buffer_occupancy_manager final : public scheduler_ static lcid_t get_lcid(bearer_key key) { return uint_to_lcid(key / MAX_NOF_DU_UES); } public: - ue_dl_buffer_occupancy_manager(ue_event_manager& parent_) : parent(parent_) + ue_dl_buffer_occupancy_manager(ue_event_manager& parent_) : parent(parent_), pending_evs(NOF_BEARER_KEYS) { - pending_evs.reserve(NOF_BEARER_KEYS); std::fill(ue_dl_bo_table.begin(), ue_dl_bo_table.end(), -1); } @@ -45,17 +44,18 @@ class ue_event_manager::ue_dl_buffer_occupancy_manager final : public scheduler_ } // Signal that this bearer needs its BO state updated. - pending_evs.push(key); + if (not pending_evs.try_push(key)) { + parent.logger.warning("ue={} lcid={}: Discarding DL buffer occupancy update. Cause: Event queue is full", + rlc_dl_bo.ue_index, + rlc_dl_bo.lcid); + } } void slot_indication(slot_point sl) { - // Retrieve pending UEs. - pending_evs.slot_indication(); - span ues_to_process = pending_evs.get_events(); - // Process RLC buffer updates of pending UEs. - for (bearer_key key : ues_to_process) { + bearer_key key; + while (pending_evs.try_pop(key)) { // Recreate latest DL BO update. dl_buffer_state_indication_message dl_bo; // > Extract UE index and LCID. @@ -93,12 +93,16 @@ class ue_event_manager::ue_dl_buffer_occupancy_manager final : public scheduler_ } private: + using ue_event_queue = + concurrent_queue; + ue_event_manager& parent; // Table of pending DL Buffer Occupancy values. -1 means that no DL Buffer Occupancy is set. std::array, NOF_BEARER_KEYS> ue_dl_bo_table; - slot_event_list pending_evs; + // Queue of {UE Id, LCID} pairs with pending DL Buffer Occupancy updates. + ue_event_queue pending_evs; }; // Initial capacity for the common and cell event lists, in order to avoid std::vector reallocations. We use the max @@ -657,10 +661,11 @@ void ue_event_manager::handle_error_indication(slot_point void ue_event_manager::process_common(slot_point sl, du_cell_index_t cell_index) { bool new_slot_detected = last_sl != sl; - if (new_slot_detected) { - // Pop pending common events. - last_sl = sl; + if (not new_slot_detected) { + // This slot has already been processed. + return; } + last_sl = sl; // Process events for UEs whose PCell matches cell_index argument. common_event_t ev{MAX_NOF_DU_UES, []() {}}; @@ -674,16 +679,12 @@ void ue_event_manager::process_common(slot_point sl, du_cell_index_t cell_index) log_invalid_ue_index(ev.ue_index); continue; } - if (ue_db[ev.ue_index].get_pcell().cell_index == cell_index) { - // If we are currently processing PCell. - ev.callback(); - } + ev.callback(); } } - if (new_slot_detected) { - dl_bo_mng->slot_indication(sl); - } + // Process pending DL Buffer Occupancy reports. + dl_bo_mng->slot_indication(sl); } void ue_event_manager::process_cell_specific(du_cell_index_t cell_index) diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.h b/lib/scheduler/ue_scheduling/ue_event_manager.h index 1d637a69bf..7e929c4e0b 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.h +++ b/lib/scheduler/ue_scheduling/ue_event_manager.h @@ -12,7 +12,6 @@ #include "../config/sched_config_manager.h" #include "../slicing/slice_scheduler.h" -#include "../support/slot_event_list.h" #include "ue.h" #include "ue_fallback_scheduler.h" #include "srsran/adt/concurrent_queue.h" From 835e342058ecfe5f171b29c7d38c7d555ab39314 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 26 Sep 2024 19:12:00 +0200 Subject: [PATCH 154/174] sched: clean ue_event_manager warning logs --- .../ue_scheduling/ue_event_manager.cpp | 442 +++++++++--------- 1 file changed, 224 insertions(+), 218 deletions(-) diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.cpp b/lib/scheduler/ue_scheduling/ue_event_manager.cpp index c4db0d9782..ca066d9961 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.cpp +++ b/lib/scheduler/ue_scheduling/ue_event_manager.cpp @@ -131,150 +131,154 @@ void ue_event_manager::handle_ue_creation(ue_config_update_event ev) ue_creation_command{ev.next_config(), ev.get_fallback_command().has_value() and ev.get_fallback_command().value(), *du_cells[ev.next_config().pcell_common_cfg().cell_index].cell_harqs}); + const du_ue_index_t ue_idx = u->ue_index; + + auto handle_ue_creation_impl = [this, u = std::move(u), ev = std::move(ev)]() mutable { + if (ue_db.contains(u->ue_index)) { + logger.error("ue={} rnti={}: Discarding UE creation. Cause: A UE with the same index already exists", + u->ue_index, + u->crnti); + ev.abort(); + return; + } + + // Insert UE in UE repository. + du_ue_index_t ueidx = u->ue_index; + rnti_t rnti = u->crnti; + du_cell_index_t pcell_index = u->get_pcell().cell_index; + ue_db.add_ue(std::move(u)); + + const auto& added_ue = ue_db[ueidx]; + for (unsigned i = 0, e = added_ue.nof_cells(); i != e; ++i) { + // Update UCI scheduler with new UE UCI resources. + du_cells[pcell_index].uci_sched->add_ue(added_ue.get_cell(to_ue_cell_index(i)).cfg()); + + // Add UE to slice scheduler. + // Note: This action only has effect when UE is created in non-fallback mode. + du_cells[pcell_index].slice_sched->add_ue(ueidx); + } + + // Log Event. + du_cells[pcell_index].ev_logger->enqueue(scheduler_event_logger::ue_creation_event{ueidx, rnti, pcell_index}); + }; // Defer UE object addition to ue list to the slot indication handler. - if (not common_events.try_push(common_event_t{ - INVALID_DU_UE_INDEX, [this, u = std::move(u), ev = std::move(ev)]() mutable { - if (ue_db.contains(u->ue_index)) { - logger.error("ue={} rnti={}: Discarding UE creation. Cause: A UE with the same index already exists", - u->ue_index, - u->crnti); - ev.abort(); - return; - } - - // Insert UE in UE repository. - du_ue_index_t ueidx = u->ue_index; - rnti_t rnti = u->crnti; - du_cell_index_t pcell_index = u->get_pcell().cell_index; - ue_db.add_ue(std::move(u)); - - const auto& added_ue = ue_db[ueidx]; - for (unsigned i = 0, e = added_ue.nof_cells(); i != e; ++i) { - // Update UCI scheduler with new UE UCI resources. - du_cells[pcell_index].uci_sched->add_ue(added_ue.get_cell(to_ue_cell_index(i)).cfg()); - - // Add UE to slice scheduler. - // Note: This action only has effect when UE is created in non-fallback mode. - du_cells[pcell_index].slice_sched->add_ue(ueidx); - } - - // Log Event. - du_cells[pcell_index].ev_logger->enqueue( - scheduler_event_logger::ue_creation_event{ueidx, rnti, pcell_index}); - }})) { - logger.warning("Discarding UE creation. Cause: Event queue is full"); + if (not common_events.try_push(common_event_t{INVALID_DU_UE_INDEX, std::move(handle_ue_creation_impl)})) { + logger.warning("ue={}: Discarding UE creation. Cause: Event queue is full", ue_idx); } } void ue_event_manager::handle_ue_reconfiguration(ue_config_update_event ev) { - du_ue_index_t ue_index = ev.get_ue_index(); - if (not common_events.try_push( - common_event_t{ue_index, [this, ev = std::move(ev)]() mutable { - const du_ue_index_t ue_idx = ev.get_ue_index(); - if (not ue_db.contains(ue_idx)) { - log_invalid_ue_index(ue_idx, "UE Reconfig Request"); - ev.abort(); - return; - } - auto& u = ue_db[ue_idx]; - - // If a UE carrier has been removed, remove the UE from the respective slice scheduler. - // Update UCI scheduler with cell changes. - for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { - auto& ue_cc = u.get_cell(to_ue_cell_index(i)); - if (not ev.next_config().contains(ue_cc.cell_index)) { - // UE carrier is being removed. - // Update UE UCI resources in UCI scheduler. - du_cells[ue_cc.cell_index].uci_sched->rem_ue(ue_cc.cfg()); - // Schedule removal of UE in slice scheduler. - du_cells[ue_cc.cell_index].slice_sched->rem_ue(ue_idx); - } else { - // UE carrier is being reconfigured. - du_cells[ue_cc.cell_index].uci_sched->reconf_ue( - ev.next_config().ue_cell_cfg(ue_cc.cell_index), ue_cc.cfg()); - } - } - for (unsigned i = 0, e = ev.next_config().nof_cells(); i != e; ++i) { - const auto& new_ue_cc_cfg = ev.next_config().ue_cell_cfg(to_ue_cell_index(i)); - auto* ue_cc = u.find_cell(new_ue_cc_cfg.cell_cfg_common.cell_index); - if (ue_cc == nullptr) { - // New UE carrier is being added. - du_cells[new_ue_cc_cfg.cell_cfg_common.cell_index].uci_sched->add_ue(new_ue_cc_cfg); - } - } - - // Configure existing UE. - ue_db[ue_idx].handle_reconfiguration_request(ue_reconf_command{ev.next_config()}); - - // Update slice scheduler. - for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { - const auto& ue_cc = u.get_cell(to_ue_cell_index(i)); - // Reconfigure UE in slice scheduler. - du_cells[ue_cc.cell_index].slice_sched->reconf_ue(u.ue_index); - } + const du_ue_index_t ue_index = ev.get_ue_index(); - // Log event. - du_cells[u.get_pcell().cell_index].ev_logger->enqueue( - scheduler_event_logger::ue_reconf_event{ue_idx, u.crnti}); - }})) { - logger.warning("Discarding UE reconfiguration. Cause: Event queue is full"); + auto handle_ue_reconf_impl = [this, ev = std::move(ev)]() mutable { + const du_ue_index_t ue_idx = ev.get_ue_index(); + if (not ue_db.contains(ue_idx)) { + log_invalid_ue_index(ue_idx, "UE Reconfig Request"); + ev.abort(); + return; + } + auto& u = ue_db[ue_idx]; + + // If a UE carrier has been removed, remove the UE from the respective slice scheduler. + // Update UCI scheduler with cell changes. + for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { + auto& ue_cc = u.get_cell(to_ue_cell_index(i)); + if (not ev.next_config().contains(ue_cc.cell_index)) { + // UE carrier is being removed. + // Update UE UCI resources in UCI scheduler. + du_cells[ue_cc.cell_index].uci_sched->rem_ue(ue_cc.cfg()); + // Schedule removal of UE in slice scheduler. + du_cells[ue_cc.cell_index].slice_sched->rem_ue(ue_idx); + } else { + // UE carrier is being reconfigured. + du_cells[ue_cc.cell_index].uci_sched->reconf_ue(ev.next_config().ue_cell_cfg(ue_cc.cell_index), ue_cc.cfg()); + } + } + for (unsigned i = 0, e = ev.next_config().nof_cells(); i != e; ++i) { + const auto& new_ue_cc_cfg = ev.next_config().ue_cell_cfg(to_ue_cell_index(i)); + auto* ue_cc = u.find_cell(new_ue_cc_cfg.cell_cfg_common.cell_index); + if (ue_cc == nullptr) { + // New UE carrier is being added. + du_cells[new_ue_cc_cfg.cell_cfg_common.cell_index].uci_sched->add_ue(new_ue_cc_cfg); + } + } + + // Configure existing UE. + ue_db[ue_idx].handle_reconfiguration_request(ue_reconf_command{ev.next_config()}); + + // Update slice scheduler. + for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { + const auto& ue_cc = u.get_cell(to_ue_cell_index(i)); + // Reconfigure UE in slice scheduler. + du_cells[ue_cc.cell_index].slice_sched->reconf_ue(u.ue_index); + } + + // Log event. + du_cells[u.get_pcell().cell_index].ev_logger->enqueue(scheduler_event_logger::ue_reconf_event{ue_idx, u.crnti}); + }; + + if (not common_events.try_push(common_event_t{ue_index, std::move(handle_ue_reconf_impl)})) { + logger.warning("ue={}: Discarding UE reconfiguration. Cause: Event queue is full", ue_index); } } void ue_event_manager::handle_ue_deletion(ue_config_delete_event ev) { const du_ue_index_t ue_index = ev.ue_index(); - if (not common_events.try_push(common_event_t{ - ue_index, [this, ev = std::move(ev)]() mutable { - const du_ue_index_t ue_idx = ev.ue_index(); - if (not ue_db.contains(ue_idx)) { - logger.warning("Received request to delete ue={} that does not exist", ue_idx); - return; - } - const auto& u = ue_db[ue_idx]; - const rnti_t rnti = u.crnti; - du_cell_index_t pcell_idx = u.get_pcell().cell_index; - - for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { - // Update UCI scheduling by removing existing UE UCI resources. - du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].uci_sched->rem_ue(u.get_pcell().cfg()); - // Schedule removal of UE from slice scheduler. - du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].slice_sched->rem_ue(ue_idx); - } - - // Schedule UE removal from repository. - ue_db.schedule_ue_rem(std::move(ev)); - - // Log UE removal event. - du_cells[pcell_idx].ev_logger->enqueue(sched_ue_delete_message{ue_idx, rnti}); - }})) { - logger.warning("Discarding UE deletion. Cause: Event queue is full"); + + auto handle_ue_deletion_impl = [this, ev = std::move(ev)]() mutable { + const du_ue_index_t ue_idx = ev.ue_index(); + if (not ue_db.contains(ue_idx)) { + logger.warning("Received request to delete ue={} that does not exist", ue_idx); + return; + } + const auto& u = ue_db[ue_idx]; + const rnti_t rnti = u.crnti; + du_cell_index_t pcell_idx = u.get_pcell().cell_index; + + for (unsigned i = 0, e = u.nof_cells(); i != e; ++i) { + // Update UCI scheduling by removing existing UE UCI resources. + du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].uci_sched->rem_ue(u.get_pcell().cfg()); + // Schedule removal of UE from slice scheduler. + du_cells[u.get_cell(to_ue_cell_index(i)).cell_index].slice_sched->rem_ue(ue_idx); + } + + // Schedule UE removal from repository. + ue_db.schedule_ue_rem(std::move(ev)); + + // Log UE removal event. + du_cells[pcell_idx].ev_logger->enqueue(sched_ue_delete_message{ue_idx, rnti}); + }; + + if (not common_events.try_push(common_event_t{ue_index, std::move(handle_ue_deletion_impl)})) { + logger.warning("ue={}: Discarding UE deletion. Cause: Event queue is full", ue_index); } } void ue_event_manager::handle_ue_config_applied(du_ue_index_t ue_idx) { - if (not common_events.try_push(common_event_t{ - ue_idx, [this, ue_idx]() { - if (not ue_db.contains(ue_idx)) { - logger.warning("Received config application confirmation for ue={} that does not exist", ue_idx); - return; - } - ue& u = ue_db[ue_idx]; - auto& pcell = du_cells[u.get_pcell().cell_index]; - - // Log UE config applied event. - pcell.ev_logger->enqueue(scheduler_event_logger::ue_cfg_applied_event{ue_idx, u.crnti}); - - // Remove UE from fallback mode. - u.get_pcell().set_fallback_state(false); - - // Add UE to slice scheduler, once it leaves fallback mode. - pcell.slice_sched->config_applied(ue_idx); - }})) { - logger.warning("Discarding UE config applied. Cause: Event queue is full"); + auto handle_ue_config_applied_impl = [this, ue_idx]() { + if (not ue_db.contains(ue_idx)) { + logger.warning("Received config application confirmation for ue={} that does not exist", ue_idx); + return; + } + ue& u = ue_db[ue_idx]; + auto& pcell = du_cells[u.get_pcell().cell_index]; + + // Log UE config applied event. + pcell.ev_logger->enqueue(scheduler_event_logger::ue_cfg_applied_event{ue_idx, u.crnti}); + + // Remove UE from fallback mode. + u.get_pcell().set_fallback_state(false); + + // Add UE to slice scheduler, once it leaves fallback mode. + pcell.slice_sched->config_applied(ue_idx); + }; + + if (not common_events.try_push(common_event_t{ue_idx, handle_ue_config_applied_impl})) { + logger.warning("ue={}: Discarding UE config applied event. Cause: Event queue is full", ue_idx); } } @@ -282,38 +286,39 @@ void ue_event_manager::handle_ul_bsr_indication(const ul_bsr_indication_message& { srsran_sanity_check(cell_exists(bsr_ind.cell_index), "Invalid cell index"); - if (not common_events.try_push( - common_event_t{bsr_ind.ue_index, [this, bsr_ind]() { - if (not ue_db.contains(bsr_ind.ue_index)) { - log_invalid_ue_index(bsr_ind.ue_index, "BSR"); - return; - } - auto& u = ue_db[bsr_ind.ue_index]; - du_cell_index_t pcell_idx = u.get_pcell().cell_index; + auto handle_ul_bsr_ind_impl = [this, bsr_ind]() { + if (not ue_db.contains(bsr_ind.ue_index)) { + log_invalid_ue_index(bsr_ind.ue_index, "BSR"); + return; + } + auto& u = ue_db[bsr_ind.ue_index]; + du_cell_index_t pcell_idx = u.get_pcell().cell_index; - // Handle event. - u.handle_bsr_indication(bsr_ind); + // Handle event. + u.handle_bsr_indication(bsr_ind); - if (u.get_pcell().is_in_fallback_mode()) { - // Signal SRB fallback scheduler with the new SRB0/SRB1 buffer state. - du_cells[pcell_idx].fallback_sched->handle_ul_bsr_indication(bsr_ind.ue_index, bsr_ind); - } + if (u.get_pcell().is_in_fallback_mode()) { + // Signal SRB fallback scheduler with the new SRB0/SRB1 buffer state. + du_cells[pcell_idx].fallback_sched->handle_ul_bsr_indication(bsr_ind.ue_index, bsr_ind); + } - // Log event. - if (du_cells[pcell_idx].ev_logger->enabled()) { - scheduler_event_logger::bsr_event event{}; - event.ue_index = bsr_ind.ue_index; - event.rnti = bsr_ind.crnti; - event.type = bsr_ind.type; - event.reported_lcgs = bsr_ind.reported_lcgs; - event.tot_ul_pending_bytes = units::bytes{u.pending_ul_newtx_bytes()}; - du_cells[pcell_idx].ev_logger->enqueue(event); - } + // Log event. + if (du_cells[pcell_idx].ev_logger->enabled()) { + scheduler_event_logger::bsr_event event{}; + event.ue_index = bsr_ind.ue_index; + event.rnti = bsr_ind.crnti; + event.type = bsr_ind.type; + event.reported_lcgs = bsr_ind.reported_lcgs; + event.tot_ul_pending_bytes = units::bytes{u.pending_ul_newtx_bytes()}; + du_cells[pcell_idx].ev_logger->enqueue(event); + } - // Notify metrics handler. - metrics_handler.handle_ul_bsr_indication(bsr_ind); - }})) { - logger.warning("Discarding UE BSR. Cause: Event queue is full"); + // Notify metrics handler. + metrics_handler.handle_ul_bsr_indication(bsr_ind); + }; + + if (not common_events.try_push(common_event_t{bsr_ind.ue_index, handle_ul_bsr_ind_impl})) { + logger.warning("ue={}: Discarding UE BSR. Cause: Event queue is full", bsr_ind.ue_index); } } @@ -510,24 +515,25 @@ void ue_event_manager::handle_uci_indication(const uci_indication& ind) void ue_event_manager::handle_dl_mac_ce_indication(const dl_mac_ce_indication& ce) { - if (not common_events.try_push(common_event_t{ - ce.ue_index, [this, ce]() { - if (not ue_db.contains(ce.ue_index)) { - log_invalid_ue_index(ce.ue_index, "DL MAC CE"); - return; - } - auto& u = ue_db[ce.ue_index]; - u.handle_dl_mac_ce_indication(ce); - - // Notify SRB fallback scheduler upon receiving ConRes CE indication. - if (ce.ce_lcid == lcid_dl_sch_t::UE_CON_RES_ID) { - du_cells[ue_db[ce.ue_index].get_pcell().cell_index].fallback_sched->handle_conres_indication(ce.ue_index); - } - - // Log event. - du_cells[u.get_pcell().cell_index].ev_logger->enqueue(ce); - }})) { - logger.warning("DL MAC CE discarded. Cause: Event queue is full"); + auto handle_mac_ce_impl = [this, ce]() { + if (not ue_db.contains(ce.ue_index)) { + log_invalid_ue_index(ce.ue_index, "DL MAC CE"); + return; + } + auto& u = ue_db[ce.ue_index]; + u.handle_dl_mac_ce_indication(ce); + + // Notify SRB fallback scheduler upon receiving ConRes CE indication. + if (ce.ce_lcid == lcid_dl_sch_t::UE_CON_RES_ID) { + du_cells[ue_db[ce.ue_index].get_pcell().cell_index].fallback_sched->handle_conres_indication(ce.ue_index); + } + + // Log event. + du_cells[u.get_pcell().cell_index].ev_logger->enqueue(ce); + }; + + if (not common_events.try_push(common_event_t{ce.ue_index, handle_mac_ce_impl})) { + logger.warning("ue={} lcid={}: DL MAC CE discarded. Cause: Event queue is full", ce.ue_index, ce.ce_lcid); } } @@ -608,53 +614,53 @@ void ue_event_manager::handle_error_indication(slot_point du_cell_index_t cell_index, scheduler_slot_handler::error_outcome event) { - if (not common_events.try_push(common_event_t{ - INVALID_DU_UE_INDEX, [this, sl_tx, cell_index, event]() { - // Handle Error Indication. - - const cell_slot_resource_allocator* prev_slot_result = du_cells[cell_index].res_grid->get_history(sl_tx); - if (prev_slot_result == nullptr) { - logger.warning( - "cell={}, slot={}: Discarding error indication. Cause: Scheduler results associated with the slot " - "of the error indication have already been erased", - cell_index, - sl_tx); - return; - } - - // In case DL PDCCHs were skipped, there will be the following consequences: - // - The UE will not decode the PDSCH and will not send the respective UCI. - // - The UE won't update the HARQ NDI, if new HARQ TB. - // - The UCI indication coming later from the lower layers will likely contain a HARQ-ACK=DTX. - // In case UL PDCCHs were skipped, there will be the following consequences: - // - The UE will not decode the PUSCH. - // - The UE won't update the HARQ NDI, if new HARQ TB. - // - The CRC indication coming from the lower layers will likely be CRC=KO. - // - Any UCI in the respective PUSCH will be likely reported as HARQ-ACK=DTX. - // In neither of the cases, the HARQs will timeout, because we did not lose the UCI/CRC indications in the - // lower layers. We do not need to cancel associated PUSCH grant (in UL PDCCH case) because it is important - // that the PUSCH "new_data" flag reaches the lower layers, telling them whether the UL HARQ buffer needs to - // be reset or not. Cancelling HARQ retransmissions is dangerous as it increases the chances of NDI - // ambiguity. - - // In case of PDSCH grants being discarded, there will be the following consequences: - // - If the PDCCH was not discarded,the UE will fail to decode the PDSCH and will send an HARQ-ACK=NACK. The - // scheduler will retransmit the respective DL HARQ. No actions required. - - // In case of PUCCH and PUSCH grants being discarded. - if (event.pusch_and_pucch_discarded) { - handle_discarded_pusch(*prev_slot_result, ue_db); - - handle_discarded_pucch(*prev_slot_result, ue_db); - } - - // Log event. - du_cells[cell_index].ev_logger->enqueue(scheduler_event_logger::error_indication_event{sl_tx, event}); - - // Report metrics. - metrics_handler.handle_error_indication(); - }})) { - logger.warning("Discarding error indication. Cause: Event queue is full"); + auto handle_error_impl = [this, sl_tx, cell_index, event]() { + // Handle Error Indication. + + const cell_slot_resource_allocator* prev_slot_result = du_cells[cell_index].res_grid->get_history(sl_tx); + if (prev_slot_result == nullptr) { + logger.warning("cell={}, slot={}: Discarding error indication. Cause: Scheduler results associated with the slot " + "of the error indication have already been erased", + cell_index, + sl_tx); + return; + } + + // In case DL PDCCHs were skipped, there will be the following consequences: + // - The UE will not decode the PDSCH and will not send the respective UCI. + // - The UE won't update the HARQ NDI, if new HARQ TB. + // - The UCI indication coming later from the lower layers will likely contain a HARQ-ACK=DTX. + // In case UL PDCCHs were skipped, there will be the following consequences: + // - The UE will not decode the PUSCH. + // - The UE won't update the HARQ NDI, if new HARQ TB. + // - The CRC indication coming from the lower layers will likely be CRC=KO. + // - Any UCI in the respective PUSCH will be likely reported as HARQ-ACK=DTX. + // In neither of the cases, the HARQs will timeout, because we did not lose the UCI/CRC indications in the + // lower layers. We do not need to cancel associated PUSCH grant (in UL PDCCH case) because it is important + // that the PUSCH "new_data" flag reaches the lower layers, telling them whether the UL HARQ buffer needs to + // be reset or not. Cancelling HARQ retransmissions is dangerous as it increases the chances of NDI + // ambiguity. + + // In case of PDSCH grants being discarded, there will be the following consequences: + // - If the PDCCH was not discarded,the UE will fail to decode the PDSCH and will send an HARQ-ACK=NACK. The + // scheduler will retransmit the respective DL HARQ. No actions required. + + // In case of PUCCH and PUSCH grants being discarded. + if (event.pusch_and_pucch_discarded) { + handle_discarded_pusch(*prev_slot_result, ue_db); + + handle_discarded_pucch(*prev_slot_result, ue_db); + } + + // Log event. + du_cells[cell_index].ev_logger->enqueue(scheduler_event_logger::error_indication_event{sl_tx, event}); + + // Report metrics. + metrics_handler.handle_error_indication(); + }; + + if (not common_events.try_push(common_event_t{INVALID_DU_UE_INDEX, handle_error_impl})) { + logger.warning("Discarding error indication for slot={}. Cause: Event queue is full", sl_tx); } } From f76588835f72a5879bfe7fd81add5244f522ac1d Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 26 Sep 2024 19:32:52 +0200 Subject: [PATCH 155/174] sched: restructure config manager to detect cases when ue creation/reconf failed due to event queue being full --- lib/scheduler/config/sched_config_manager.cpp | 10 ++++++---- lib/scheduler/config/sched_config_manager.h | 2 +- lib/scheduler/ue_scheduling/ue_event_manager.cpp | 8 ++++++-- .../scheduler/test_utils/config_generators.cpp | 7 ++++++- .../ue_scheduling/fallback_scheduler_test.cpp | 2 +- .../scheduler/ue_scheduling/ue_grid_allocator_test.cpp | 1 + 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/scheduler/config/sched_config_manager.cpp b/lib/scheduler/config/sched_config_manager.cpp index f0b8f67f59..fb2976c192 100644 --- a/lib/scheduler/config/sched_config_manager.cpp +++ b/lib/scheduler/config/sched_config_manager.cpp @@ -27,14 +27,16 @@ ue_config_update_event::ue_config_update_event(du_ue_index_t ue_config_update_event::~ue_config_update_event() { if (parent != nullptr) { - // Event completed with success or failure. - parent->handle_ue_config_complete(ue_index, std::move(next_ded_cfg)); + // Event completed with failure. + parent->handle_ue_config_complete(ue_index, nullptr); } } -void ue_config_update_event::abort() +void ue_config_update_event::notify_completion() { - next_ded_cfg = nullptr; + // Event completed with success. + parent->handle_ue_config_complete(ue_index, std::move(next_ded_cfg)); + parent.reset(); } ue_config_delete_event::ue_config_delete_event(du_ue_index_t ue_index_, sched_config_manager& parent_) : diff --git a/lib/scheduler/config/sched_config_manager.h b/lib/scheduler/config/sched_config_manager.h index e9015953f0..683be61c6a 100644 --- a/lib/scheduler/config/sched_config_manager.h +++ b/lib/scheduler/config/sched_config_manager.h @@ -39,7 +39,7 @@ class ue_config_update_event const ue_configuration& next_config() const { return *next_ded_cfg; } std::optional get_fallback_command() const { return set_fallback_mode; } - void abort(); + void notify_completion(); private: du_ue_index_t ue_index = INVALID_DU_UE_INDEX; diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.cpp b/lib/scheduler/ue_scheduling/ue_event_manager.cpp index ca066d9961..6ee34b21e5 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.cpp +++ b/lib/scheduler/ue_scheduling/ue_event_manager.cpp @@ -138,7 +138,6 @@ void ue_event_manager::handle_ue_creation(ue_config_update_event ev) logger.error("ue={} rnti={}: Discarding UE creation. Cause: A UE with the same index already exists", u->ue_index, u->crnti); - ev.abort(); return; } @@ -160,6 +159,9 @@ void ue_event_manager::handle_ue_creation(ue_config_update_event ev) // Log Event. du_cells[pcell_index].ev_logger->enqueue(scheduler_event_logger::ue_creation_event{ueidx, rnti, pcell_index}); + + // Notify config manager that creation is complete with success. + ev.notify_completion(); }; // Defer UE object addition to ue list to the slot indication handler. @@ -176,7 +178,6 @@ void ue_event_manager::handle_ue_reconfiguration(ue_config_update_event ev) const du_ue_index_t ue_idx = ev.get_ue_index(); if (not ue_db.contains(ue_idx)) { log_invalid_ue_index(ue_idx, "UE Reconfig Request"); - ev.abort(); return; } auto& u = ue_db[ue_idx]; @@ -217,6 +218,9 @@ void ue_event_manager::handle_ue_reconfiguration(ue_config_update_event ev) // Log event. du_cells[u.get_pcell().cell_index].ev_logger->enqueue(scheduler_event_logger::ue_reconf_event{ue_idx, u.crnti}); + + // Notify config manager that creation is complete with success. + ev.notify_completion(); }; if (not common_events.try_push(common_event_t{ue_index, std::move(handle_ue_reconf_impl)})) { diff --git a/tests/unittests/scheduler/test_utils/config_generators.cpp b/tests/unittests/scheduler/test_utils/config_generators.cpp index dc69ee07fa..2a2bef0e43 100644 --- a/tests/unittests/scheduler/test_utils/config_generators.cpp +++ b/tests/unittests/scheduler/test_utils/config_generators.cpp @@ -68,7 +68,12 @@ const cell_configuration* test_sched_config_manager::add_cell(const sched_cell_c const ue_configuration* test_sched_config_manager::add_ue(const sched_ue_creation_request_message& cfg_req) { auto ue_ev = cfg_mng.add_ue(cfg_req); - return ue_ev.valid() ? &ue_ev.next_config() : nullptr; + if (ue_ev.valid()) { + const ue_configuration* ret = &ue_ev.next_config(); + ue_ev.notify_completion(); + return ret; + } + return nullptr; } bool test_sched_config_manager::rem_ue(du_ue_index_t ue_index) diff --git a/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp b/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp index 4cf797bc4e..41b9366d08 100644 --- a/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp +++ b/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp @@ -120,12 +120,12 @@ struct test_bench { auto u = std::make_unique(ue_creation_command{ev.next_config(), create_req.starts_in_fallback, cell_harqs}); if (ue_db.contains(create_req.ue_index)) { // UE already exists. - ev.abort(); return false; } ue_db.add_ue(std::move(u)); auto& ue = ue_db[create_req.ue_index]; ue.get_pcell().set_fallback_state(true); + ev.notify_completion(); return true; } }; diff --git a/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp b/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp index 6daf9b60a3..60b77e5c07 100644 --- a/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp +++ b/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp @@ -114,6 +114,7 @@ class ue_grid_allocator_tester : public ::testing::TestWithParam for (const auto& lc_cfg : *ue_creation_req.cfg.lc_config_list) { slice_ues[ue_creation_req.ue_index].add_logical_channel(lc_cfg.lcid, lc_cfg.lc_group); } + ev.notify_completion(); return ues[ue_creation_req.ue_index]; } From 42bdbad2542382eda8b1434dfee0d35c1dfe391b Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 27 Sep 2024 12:55:51 +0200 Subject: [PATCH 156/174] sched: refactor passing of metrics handler for a cell to the ue event manager --- lib/scheduler/cell_scheduler.cpp | 4 +- lib/scheduler/scheduler_impl.cpp | 4 +- .../ue_scheduling/ue_event_manager.cpp | 55 +++++++++---------- .../ue_scheduling/ue_event_manager.h | 44 +++++++-------- lib/scheduler/ue_scheduling/ue_scheduler.h | 2 + .../ue_scheduling/ue_scheduler_impl.cpp | 23 ++++---- .../ue_scheduling/ue_scheduler_impl.h | 5 +- 7 files changed, 62 insertions(+), 75 deletions(-) diff --git a/lib/scheduler/cell_scheduler.cpp b/lib/scheduler/cell_scheduler.cpp index e9d82df425..4e132b58ec 100644 --- a/lib/scheduler/cell_scheduler.cpp +++ b/lib/scheduler/cell_scheduler.cpp @@ -39,8 +39,8 @@ cell_scheduler::cell_scheduler(const scheduler_expert_config& s pg_sch(sched_cfg, cell_cfg, pdcch_sch, msg) { // Register new cell in the UE scheduler. - ue_sched.add_cell( - ue_scheduler_cell_params{msg.cell_index, &pdcch_sch, &pucch_alloc, &uci_alloc, &res_grid, &event_logger}); + ue_sched.add_cell(ue_scheduler_cell_params{ + msg.cell_index, &pdcch_sch, &pucch_alloc, &uci_alloc, &res_grid, &metrics, &event_logger}); } void cell_scheduler::handle_crc_indication(const ul_crc_indication& crc_ind) diff --git a/lib/scheduler/scheduler_impl.cpp b/lib/scheduler/scheduler_impl.cpp index 35bb4c7d91..8fa1a302df 100644 --- a/lib/scheduler/scheduler_impl.cpp +++ b/lib/scheduler/scheduler_impl.cpp @@ -11,7 +11,6 @@ #include "scheduler_impl.h" #include "ue_scheduling/ue_scheduler_impl.h" #include "srsran/scheduler/config/scheduler_cell_config_validator.h" -#include "srsran/scheduler/config/scheduler_ue_config_validator.h" using namespace srsran; @@ -39,8 +38,7 @@ bool scheduler_impl::handle_cell_configuration_request(const sched_cell_configur // Check if it is a new DU Cell Group. if (not groups.contains(msg.cell_group_index)) { // If it is a new group, create a new instance. - groups.emplace(msg.cell_group_index, - std::make_unique(expert_params.ue, config_notifier, *cell_metrics)); + groups.emplace(msg.cell_group_index, std::make_unique(expert_params.ue)); } // Create a new cell scheduler instance. diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.cpp b/lib/scheduler/ue_scheduling/ue_event_manager.cpp index 6ee34b21e5..0f880a55a1 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.cpp +++ b/lib/scheduler/ue_scheduling/ue_event_manager.cpp @@ -78,17 +78,18 @@ class ue_event_manager::ue_dl_buffer_occupancy_manager final : public scheduler_ // Forward DL BO update to UE. u.handle_dl_buffer_state_indication(dl_bo); + auto& du_pcell = parent.du_cells[u.get_pcell().cell_index]; if (dl_bo.lcid == LCID_SRB0 or (u.get_pcell().is_in_fallback_mode() and dl_bo.lcid == LCID_SRB1)) { // Signal SRB fallback scheduler with the new SRB0/SRB1 buffer state. - parent.du_cells[u.get_pcell().cell_index].fallback_sched->handle_dl_buffer_state_indication_srb( + du_pcell.fallback_sched->handle_dl_buffer_state_indication_srb( dl_bo.ue_index, dl_bo.lcid == LCID_SRB0, sl, dl_bo.bs); } // Log event. - parent.du_cells[u.get_pcell().cell_index].ev_logger->enqueue(dl_bo); + du_pcell.ev_logger->enqueue(dl_bo); // Report event. - parent.metrics_handler.handle_dl_buffer_state_indication(dl_bo); + du_pcell.metrics->handle_dl_buffer_state_indication(dl_bo); } } @@ -110,16 +111,12 @@ class ue_event_manager::ue_dl_buffer_occupancy_manager final : public scheduler_ static constexpr size_t COMMON_EVENT_LIST_SIZE = MAX_NOF_DU_UES * 2; static constexpr size_t CELL_EVENT_LIST_SIZE = MAX_NOF_DU_UES * 2; -ue_event_manager::ue_event_manager(ue_repository& ue_db_, cell_metrics_handler& metrics_handler_) : +ue_event_manager::ue_event_manager(ue_repository& ue_db_) : ue_db(ue_db_), - metrics_handler(metrics_handler_), logger(srslog::fetch_basic_logger("SCHED")), common_events(COMMON_EVENT_LIST_SIZE), dl_bo_mng(std::make_unique(*this)) { - for (unsigned i = 0; i != MAX_NOF_DU_CELLS; ++i) { - cell_specific_events.emplace_back(CELL_EVENT_LIST_SIZE); - } } ue_event_manager::~ue_event_manager() {} @@ -318,7 +315,7 @@ void ue_event_manager::handle_ul_bsr_indication(const ul_bsr_indication_message& } // Notify metrics handler. - metrics_handler.handle_ul_bsr_indication(bsr_ind); + du_cells[pcell_idx].metrics->handle_ul_bsr_indication(bsr_ind); }; if (not common_events.try_push(common_event_t{bsr_ind.ue_index, handle_ul_bsr_ind_impl})) { @@ -346,7 +343,7 @@ void ue_event_manager::handle_ul_phr_indication(const ul_phr_indication_message& du_cells[cell_phr.serv_cell_id].ev_logger->enqueue(event); // Notify metrics handler. - metrics_handler.handle_ul_phr_indication(phr_ind); + du_cells[cell_phr.serv_cell_id].metrics->handle_ul_phr_indication(phr_ind); }, "UL PHR", true})) { @@ -378,8 +375,8 @@ void ue_event_manager::handle_crc_indication(const ul_crc_indication& crc_ind) crc.ue_index, crc.rnti, ue_cc.cell_index, sl_rx, crc.harq_id, crc.tb_crc_success, crc.ul_sinr_dB}); // Notify metrics handler. - metrics_handler.handle_crc_indication(crc, units::bytes{(unsigned)tbs}); - metrics_handler.handle_ul_delay(crc.ue_index, last_sl - sl_rx); + du_cells[ue_cc.cell_index].metrics->handle_crc_indication(crc, units::bytes{(unsigned)tbs}); + du_cells[ue_cc.cell_index].metrics->handle_ul_delay(crc.ue_index, last_sl - sl_rx); }, "CRC", true})) { @@ -407,7 +404,7 @@ void ue_event_manager::handle_harq_ind(ue_cell& ue if (result->update == dl_harq_process::status_update::acked or result->update == dl_harq_process::status_update::nacked) { // In case the HARQ process is not waiting for more HARQ-ACK bits. Notify metrics handler with HARQ outcome. - metrics_handler.handle_dl_harq_ack( + du_cells[ue_cc.cell_index].metrics->handle_dl_harq_ack( ue_cc.ue_index, result->update == dl_harq_process::status_update::acked, tbs); } } @@ -504,7 +501,7 @@ void ue_event_manager::handle_uci_indication(const uci_indication& ind) } // Report the UCI PDU to the metrics handler. - metrics_handler.handle_uci_pdu_indication(uci_pdu); + du_cells[ue_cc.cell_index].metrics->handle_uci_pdu_indication(uci_pdu); }, "UCI", // Note: We do not warn if the UE is not found, because there is this transient period when the UE @@ -660,7 +657,7 @@ void ue_event_manager::handle_error_indication(slot_point du_cells[cell_index].ev_logger->enqueue(scheduler_event_logger::error_indication_event{sl_tx, event}); // Report metrics. - metrics_handler.handle_error_indication(); + du_cells[cell_index].metrics->handle_error_indication(); }; if (not common_events.try_push(common_event_t{INVALID_DU_UE_INDEX, handle_error_impl})) { @@ -728,23 +725,23 @@ void ue_event_manager::run(slot_point sl, du_cell_index_t cell_index) process_cell_specific(cell_index); } -void ue_event_manager::add_cell(cell_resource_allocator& cell_res_grid, - cell_harq_manager& cell_harqs, - ue_fallback_scheduler& fallback_sched, - uci_scheduler_impl& uci_sched, - scheduler_event_logger& ev_logger, - slice_scheduler& slice_sched) +void ue_event_manager::add_cell(const cell_creation_event& cell_ev) { - const du_cell_index_t cell_index = cell_res_grid.cell_index(); + const du_cell_index_t cell_index = cell_ev.cell_res_grid.cell_index(); srsran_assert(not cell_exists(cell_index), "Overwriting cell configurations not supported"); - du_cells[cell_index].cfg = &cell_res_grid.cfg; - du_cells[cell_index].res_grid = &cell_res_grid; - du_cells[cell_index].cell_harqs = &cell_harqs; - du_cells[cell_index].fallback_sched = &fallback_sched; - du_cells[cell_index].uci_sched = &uci_sched; - du_cells[cell_index].ev_logger = &ev_logger; - du_cells[cell_index].slice_sched = &slice_sched; + du_cells[cell_index].cfg = &cell_ev.cell_res_grid.cfg; + du_cells[cell_index].res_grid = &cell_ev.cell_res_grid; + du_cells[cell_index].cell_harqs = &cell_ev.cell_harqs; + du_cells[cell_index].fallback_sched = &cell_ev.fallback_sched; + du_cells[cell_index].uci_sched = &cell_ev.uci_sched; + du_cells[cell_index].slice_sched = &cell_ev.slice_sched; + du_cells[cell_index].metrics = &cell_ev.metrics; + du_cells[cell_index].ev_logger = &cell_ev.ev_logger; + + while (cell_specific_events.size() <= cell_index) { + cell_specific_events.emplace_back(CELL_EVENT_LIST_SIZE); + } } bool ue_event_manager::cell_exists(du_cell_index_t cell_index) const diff --git a/lib/scheduler/ue_scheduling/ue_event_manager.h b/lib/scheduler/ue_scheduling/ue_event_manager.h index 7e929c4e0b..c101015677 100644 --- a/lib/scheduler/ue_scheduling/ue_event_manager.h +++ b/lib/scheduler/ue_scheduling/ue_event_manager.h @@ -26,6 +26,16 @@ class scheduler_event_logger; class uci_scheduler_impl; class cell_harq_manager; +struct cell_creation_event { + cell_resource_allocator& cell_res_grid; + cell_harq_manager& cell_harqs; + ue_fallback_scheduler& fallback_sched; + uci_scheduler_impl& uci_sched; + slice_scheduler& slice_sched; + cell_metrics_handler& metrics; + scheduler_event_logger& ev_logger; +}; + /// \brief Class used to manage events that arrive to the scheduler and are directed at UEs. /// This class acts as a facade for several of the ue_scheduler subcomponents, managing the asynchronous configuration /// of the UEs and logging in a thread-safe manner. @@ -34,15 +44,10 @@ class ue_event_manager final : public sched_ue_configuration_handler, public scheduler_dl_buffer_state_indication_handler { public: - ue_event_manager(ue_repository& ue_db, cell_metrics_handler& metrics_handler); + ue_event_manager(ue_repository& ue_db); ~ue_event_manager() override; - void add_cell(cell_resource_allocator& cell_res_grid, - cell_harq_manager& cell_harqs, - ue_fallback_scheduler& fallback_sched, - uci_scheduler_impl& uci_sched, - scheduler_event_logger& ev_logger, - slice_scheduler& slice_sched); + void add_cell(const cell_creation_event& cell_ev); /// UE Add/Mod/Remove interface. void handle_ue_creation(ue_config_update_event ev) override; @@ -116,27 +121,18 @@ class ue_event_manager final : public sched_ue_configuration_handler, void handle_csi(ue_cell& ue_cc, const csi_report_data& csi_rep); ue_repository& ue_db; - cell_metrics_handler& metrics_handler; srslog::basic_logger& logger; /// List of added and configured cells. struct du_cell { - const cell_configuration* cfg = nullptr; - - cell_resource_allocator* res_grid = nullptr; - - cell_harq_manager* cell_harqs = nullptr; - - // Reference to fallback scheduler. - ue_fallback_scheduler* fallback_sched = nullptr; - - // Reference to the CSI and SR UCI scheduler. - uci_scheduler_impl* uci_sched = nullptr; - - // Reference to the slice scheduler. - slice_scheduler* slice_sched = nullptr; - - scheduler_event_logger* ev_logger = nullptr; + const cell_configuration* cfg = nullptr; + cell_resource_allocator* res_grid = nullptr; + cell_harq_manager* cell_harqs = nullptr; + ue_fallback_scheduler* fallback_sched = nullptr; + uci_scheduler_impl* uci_sched = nullptr; + slice_scheduler* slice_sched = nullptr; + cell_metrics_handler* metrics = nullptr; + scheduler_event_logger* ev_logger = nullptr; }; std::array du_cells{}; diff --git a/lib/scheduler/ue_scheduling/ue_scheduler.h b/lib/scheduler/ue_scheduling/ue_scheduler.h index c2b1c40e68..7309aed776 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler.h +++ b/lib/scheduler/ue_scheduling/ue_scheduler.h @@ -20,6 +20,7 @@ class pdcch_resource_allocator; struct cell_resource_allocator; class sched_ue_configuration_handler; class scheduler_event_logger; +class cell_metrics_handler; struct ue_scheduler_cell_params { du_cell_index_t cell_index; @@ -27,6 +28,7 @@ struct ue_scheduler_cell_params { pucch_allocator* pucch_alloc; uci_allocator* uci_alloc; cell_resource_allocator* cell_res_alloc; + cell_metrics_handler* cell_metrics; scheduler_event_logger* ev_logger; }; diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp index 6120eee1e5..7480cc157e 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.cpp @@ -10,17 +10,13 @@ #include "ue_scheduler_impl.h" #include "../logging/scheduler_metrics_handler.h" -#include "../policy/scheduler_policy_factory.h" using namespace srsran; -ue_scheduler_impl::ue_scheduler_impl(const scheduler_ue_expert_config& expert_cfg_, - sched_configuration_notifier& mac_notif, - cell_metrics_handler& metric_handler_) : +ue_scheduler_impl::ue_scheduler_impl(const scheduler_ue_expert_config& expert_cfg_) : expert_cfg(expert_cfg_), - metrics_handler(metric_handler_), ue_alloc(expert_cfg, ue_db, srslog::fetch_basic_logger("SCHED")), - event_mng(ue_db, metrics_handler), + event_mng(ue_db), logger(srslog::fetch_basic_logger("SCHED")) { } @@ -28,13 +24,14 @@ ue_scheduler_impl::ue_scheduler_impl(const scheduler_ue_expert_config& expert_cf void ue_scheduler_impl::add_cell(const ue_scheduler_cell_params& params) { ue_res_grid_view.add_cell(*params.cell_res_alloc); - cells.emplace(params.cell_index, expert_cfg, params, ue_db, metrics_handler); - event_mng.add_cell(*params.cell_res_alloc, - cells[params.cell_index].cell_harqs, - cells[params.cell_index].fallback_sched, - cells[params.cell_index].uci_sched, - *params.ev_logger, - cells[params.cell_index].slice_sched); + cells.emplace(params.cell_index, expert_cfg, params, ue_db, *params.cell_metrics); + event_mng.add_cell(cell_creation_event{*params.cell_res_alloc, + cells[params.cell_index].cell_harqs, + cells[params.cell_index].fallback_sched, + cells[params.cell_index].uci_sched, + cells[params.cell_index].slice_sched, + *params.cell_metrics, + *params.ev_logger}); ue_alloc.add_cell(params.cell_index, *params.pdcch_sched, *params.uci_alloc, *params.cell_res_alloc); } diff --git a/lib/scheduler/ue_scheduling/ue_scheduler_impl.h b/lib/scheduler/ue_scheduling/ue_scheduler_impl.h index b4c4715167..6db4a009f0 100644 --- a/lib/scheduler/ue_scheduling/ue_scheduler_impl.h +++ b/lib/scheduler/ue_scheduling/ue_scheduler_impl.h @@ -30,9 +30,7 @@ namespace srsran { class ue_scheduler_impl final : public ue_scheduler { public: - explicit ue_scheduler_impl(const scheduler_ue_expert_config& expert_cfg_, - sched_configuration_notifier& mac_notif, - cell_metrics_handler& metric_handler); + explicit ue_scheduler_impl(const scheduler_ue_expert_config& expert_cfg_); void add_cell(const ue_scheduler_cell_params& params) override; @@ -84,7 +82,6 @@ class ue_scheduler_impl final : public ue_scheduler void puxch_grant_sanitizer(cell_resource_allocator& cell_alloc); const scheduler_ue_expert_config& expert_cfg; - cell_metrics_handler& metrics_handler; // List of cells of the UE scheduler. slotted_array cells; From 856ba68c6a09b25e18d037e8469bc0f48797e2ad Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 27 Sep 2024 15:02:55 +0200 Subject: [PATCH 157/174] sched: remove unused variable from scheduler_impl --- lib/scheduler/scheduler_impl.cpp | 1 - lib/scheduler/scheduler_impl.h | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/scheduler/scheduler_impl.cpp b/lib/scheduler/scheduler_impl.cpp index 8fa1a302df..05fe931ea7 100644 --- a/lib/scheduler/scheduler_impl.cpp +++ b/lib/scheduler/scheduler_impl.cpp @@ -16,7 +16,6 @@ using namespace srsran; scheduler_impl::scheduler_impl(const scheduler_config& sched_cfg_) : expert_params(sched_cfg_.expert_params), - config_notifier(sched_cfg_.config_notifier), logger(srslog::fetch_basic_logger("SCHED")), metrics(expert_params.metrics_report_period, sched_cfg_.metrics_notifier), cfg_mng(sched_cfg_) diff --git a/lib/scheduler/scheduler_impl.h b/lib/scheduler/scheduler_impl.h index 2390050a0c..b40bcb0cd0 100644 --- a/lib/scheduler/scheduler_impl.h +++ b/lib/scheduler/scheduler_impl.h @@ -56,7 +56,6 @@ class scheduler_impl final : public mac_scheduler private: const scheduler_expert_config expert_params; - sched_configuration_notifier& config_notifier; srslog::basic_logger& logger; From e5a1d3837e6344af4d1f1d271316ad259595a4bf Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 27 Sep 2024 16:11:02 +0200 Subject: [PATCH 158/174] support: implement thread local worker pool identifiers --- .../executors/execution_context_description.h | 27 ++++++ .../support/executors/task_worker_pool.h | 26 ++---- lib/support/CMakeLists.txt | 1 + .../execution_context_description.cpp | 35 ++++++++ .../execution_context_description_setup.h | 17 ++++ lib/support/executors/task_worker_pool.cpp | 87 +++++++++++-------- 6 files changed, 140 insertions(+), 53 deletions(-) create mode 100644 include/srsran/support/executors/execution_context_description.h create mode 100644 lib/support/executors/execution_context_description.cpp create mode 100644 lib/support/executors/execution_context_description_setup.h diff --git a/include/srsran/support/executors/execution_context_description.h b/include/srsran/support/executors/execution_context_description.h new file mode 100644 index 0000000000..feb28754c4 --- /dev/null +++ b/include/srsran/support/executors/execution_context_description.h @@ -0,0 +1,27 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +namespace srsran { +namespace execution_context { + +/// \brief Get number of concurrent workers in the current execution context. +/// +/// This function will return 1 if called from within a single task worker and the number of threads of a thread pool +/// if called from within the same thread pool. +unsigned get_nof_concurrent_workers(); + +/// \brief Get the index of the current worker. If the worker is a single task_worker, this function will return 0. If +/// the worker belongs to a thread pool, it will return the index of the thread in the pool. +unsigned get_worker_index(); + +} // namespace execution_context +} // namespace srsran \ No newline at end of file diff --git a/include/srsran/support/executors/task_worker_pool.h b/include/srsran/support/executors/task_worker_pool.h index 7ffb683ba2..0380d39d2d 100644 --- a/include/srsran/support/executors/task_worker_pool.h +++ b/include/srsran/support/executors/task_worker_pool.h @@ -18,16 +18,15 @@ #include "srsran/support/executors/task_executor.h" namespace srsran { - namespace detail { // Pool of workers with no associated task enqueueing policy. class base_worker_pool { public: - base_worker_pool(unsigned nof_workers_, - const std::string& worker_pool_name, - const std::function& run_tasks_job, + base_worker_pool(unsigned nof_workers_, + const std::string& worker_pool_name, + const std::function(unsigned)>& worker_task_factory, os_thread_realtime_priority prio = os_thread_realtime_priority::no_realtime(), span cpu_masks = {}); base_worker_pool(const base_worker_pool&) = delete; @@ -48,6 +47,9 @@ class base_worker_pool // List of workers belonging to the worker pool. std::vector worker_threads; + +protected: + srslog::basic_logger& logger = srslog::fetch_basic_logger("ALL"); }; class base_priority_task_queue @@ -141,11 +143,6 @@ class priority_task_worker_pool : public detail::base_priority_task_queue, publi /// \brief Wait for all the currently enqueued tasks to complete. If more tasks get enqueued after this function call /// those tasks are not accounted for in the waiting. void wait_pending_tasks(); - -private: - std::function create_pop_loop_task(); - - srslog::basic_logger& logger = srslog::fetch_basic_logger("ALL"); }; /// \brief Simple pool of task workers/threads. The workers share the same queue of task and do not perform @@ -165,11 +162,7 @@ class task_worker_pool : public detail::base_task_queue, public det unsigned qsize_, std::chrono::microseconds wait_sleep_time = std::chrono::microseconds{100}, os_thread_realtime_priority prio = os_thread_realtime_priority::no_realtime(), - span cpu_masks = {}) : - detail::base_task_queue(qsize_, wait_sleep_time), - detail::base_worker_pool(nof_workers_, std::move(worker_pool_name), create_pop_loop_task(), prio, cpu_masks) - { - } + span cpu_masks = {}); ~task_worker_pool(); /// \brief Push a new task to be processed by the worker pool. If the task queue is full, it skips the task and @@ -194,11 +187,6 @@ class task_worker_pool : public detail::base_task_queue, public det /// \brief Wait for all the currently enqueued tasks to complete. If more tasks get enqueued after this function call /// those tasks are not accounted for in the waiting. void wait_pending_tasks(); - -private: - std::function create_pop_loop_task(); - - srslog::basic_logger& logger = srslog::fetch_basic_logger("ALL"); }; extern template class task_worker_pool; diff --git a/lib/support/CMakeLists.txt b/lib/support/CMakeLists.txt index 8988a3e9e1..b26a47e4b4 100644 --- a/lib/support/CMakeLists.txt +++ b/lib/support/CMakeLists.txt @@ -16,6 +16,7 @@ set(SOURCES executors/task_worker.cpp executors/task_worker_pool.cpp executors/unique_thread.cpp + executors/execution_context_description.cpp backtrace.cpp bit_encoding.cpp byte_buffer.cpp diff --git a/lib/support/executors/execution_context_description.cpp b/lib/support/executors/execution_context_description.cpp new file mode 100644 index 0000000000..c2b422971e --- /dev/null +++ b/lib/support/executors/execution_context_description.cpp @@ -0,0 +1,35 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsran/support/executors/execution_context_description.h" +#include "execution_context_description_setup.h" +#include "srsran/support/srsran_assert.h" + +using namespace srsran; + +thread_local unsigned nof_concurrent_workers = 1; +thread_local unsigned worker_index = 0; + +unsigned srsran::execution_context::get_nof_concurrent_workers() +{ + return nof_concurrent_workers; +} + +unsigned srsran::execution_context::get_worker_index() +{ + return worker_index; +} + +void srsran::execution_context::set_worker_description(unsigned nof_concurrent_workers_, unsigned worker_index_) +{ + srsran_sanity_check(nof_concurrent_workers_ > 0, "Invalid number of workers"); + nof_concurrent_workers = nof_concurrent_workers_; + worker_index = worker_index_; +} diff --git a/lib/support/executors/execution_context_description_setup.h b/lib/support/executors/execution_context_description_setup.h new file mode 100644 index 0000000000..6910c45ba7 --- /dev/null +++ b/lib/support/executors/execution_context_description_setup.h @@ -0,0 +1,17 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +namespace srsran { +namespace execution_context { + +void set_worker_description(unsigned nof_concurrent_workers, unsigned worker_index); + +} +} // namespace srsran \ No newline at end of file diff --git a/lib/support/executors/task_worker_pool.cpp b/lib/support/executors/task_worker_pool.cpp index ccafcd2bf9..15ae11a651 100644 --- a/lib/support/executors/task_worker_pool.cpp +++ b/lib/support/executors/task_worker_pool.cpp @@ -9,15 +9,39 @@ */ #include "srsran/support/executors/task_worker_pool.h" +#include "execution_context_description_setup.h" #include using namespace srsran; -detail::base_worker_pool::base_worker_pool(unsigned nof_workers_, - const std::string& worker_pool_name, - const std::function& run_tasks_job, - os_thread_realtime_priority prio, - span cpu_masks) : +namespace { + +// Creates the task that will be run by each instantiated worker +template +std::function worker_task_factory(Queue& queue, unsigned nof_workers, unsigned worker_idx) +{ + return [&queue, nof_workers, worker_idx]() { + // setup worker execution context. + execution_context::set_worker_description(nof_workers, worker_idx); + + // start worker pop loop. + while (true) { + unique_task job; + if (not queue.pop_blocking(job)) { + break; + } + job(); + } + }; +} + +} // namespace + +detail::base_worker_pool::base_worker_pool(unsigned nof_workers_, + const std::string& worker_pool_name, + const std::function(unsigned)>& worker_task_factory, + os_thread_realtime_priority prio, + span cpu_masks) : pool_name(worker_pool_name) { worker_threads.reserve(nof_workers_); @@ -30,11 +54,11 @@ detail::base_worker_pool::base_worker_pool(unsigned // Task dispatched to workers of the pool. for (unsigned i = 0; i != nof_workers_; ++i) { if (cpu_masks.empty()) { - worker_threads.emplace_back(fmt::format("{}#{}", worker_pool_name, i), prio, run_tasks_job); + worker_threads.emplace_back(fmt::format("{}#{}", worker_pool_name, i), prio, worker_task_factory(i)); } else { // Check whether a single mask for all workers should be used. os_sched_affinity_bitmask cpu_mask = (cpu_masks.size() == 1) ? cpu_masks[0] : cpu_masks[i]; - worker_threads.emplace_back(fmt::format("{}#{}", worker_pool_name, i), prio, cpu_mask, run_tasks_job); + worker_threads.emplace_back(fmt::format("{}#{}", worker_pool_name, i), prio, cpu_mask, worker_task_factory(i)); } } } @@ -55,7 +79,12 @@ priority_task_worker_pool::priority_task_worker_pool(std::string os_thread_realtime_priority prio, span cpu_masks) : detail::base_priority_task_queue(queue_params, wait_sleep_time), - detail::base_worker_pool(nof_workers_, std::move(worker_pool_name), create_pop_loop_task(), prio, cpu_masks) + detail::base_worker_pool( + nof_workers_, + std::move(worker_pool_name), + [this, nof_workers_](unsigned worker_idx) { return worker_task_factory(this->queue, nof_workers_, worker_idx); }, + prio, + cpu_masks) { report_fatal_error_if_not(nof_workers_ > 0, "Number of workers of a thread pool must be greater than 0"); srsran_assert(queue_params.size() >= 2, "Number of queues in a prioritized thread pool must be greater than 1"); @@ -129,21 +158,25 @@ void priority_task_worker_pool::wait_pending_tasks() cvar_caller_return.wait(lock, [&counter_caller]() { return counter_caller == 0; }); } -std::function priority_task_worker_pool::create_pop_loop_task() +// ---- non-prioritized task worker pool + +template +task_worker_pool::task_worker_pool(std::string worker_pool_name, + unsigned nof_workers_, + unsigned qsize_, + std::chrono::microseconds wait_sleep_time, + os_thread_realtime_priority prio, + span cpu_masks) : + detail::base_task_queue(qsize_, wait_sleep_time), + detail::base_worker_pool( + nof_workers_, + std::move(worker_pool_name), + [this, nof_workers_](unsigned worker_idx) { return worker_task_factory(this->queue, nof_workers_, worker_idx); }, + prio, + cpu_masks) { - return [this]() { - unique_task job; - while (true) { - if (not this->queue.pop_blocking(job)) { - break; - } - job(); - } - }; } -// ---- non-prioritized task worker pool - template task_worker_pool::~task_worker_pool() { @@ -164,20 +197,6 @@ void task_worker_pool::stop() } } -template -std::function task_worker_pool::create_pop_loop_task() -{ - return [this]() { - while (true) { - unique_task job; - if (not this->queue.pop_blocking(job)) { - break; - } - job(); - } - }; -} - template void task_worker_pool::wait_pending_tasks() { From 0395340399964eabf7d8980cf098325a1d56e871 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 27 Sep 2024 17:27:30 +0200 Subject: [PATCH 159/174] support: rename helpers for execution context description --- .../support/executors/execution_context_description.h | 8 ++++---- lib/support/executors/execution_context_description.cpp | 7 ++++--- .../executors/execution_context_description_setup.h | 5 +++-- lib/support/executors/task_worker_pool.cpp | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/srsran/support/executors/execution_context_description.h b/include/srsran/support/executors/execution_context_description.h index feb28754c4..c6cd6992a6 100644 --- a/include/srsran/support/executors/execution_context_description.h +++ b/include/srsran/support/executors/execution_context_description.h @@ -17,11 +17,11 @@ namespace execution_context { /// /// This function will return 1 if called from within a single task worker and the number of threads of a thread pool /// if called from within the same thread pool. -unsigned get_nof_concurrent_workers(); +[[nodiscard]] unsigned get_current_nof_concurrent_workers(); -/// \brief Get the index of the current worker. If the worker is a single task_worker, this function will return 0. If -/// the worker belongs to a thread pool, it will return the index of the thread in the pool. -unsigned get_worker_index(); +/// \brief Get the index of the worker in the current execution context. If the worker is a single task_worker, this +// function will return 0. If the worker belongs to a thread pool, it will return the index of the thread in the pool. +[[nodiscard]] unsigned get_current_worker_index(); } // namespace execution_context } // namespace srsran \ No newline at end of file diff --git a/lib/support/executors/execution_context_description.cpp b/lib/support/executors/execution_context_description.cpp index c2b422971e..58a8cca8d9 100644 --- a/lib/support/executors/execution_context_description.cpp +++ b/lib/support/executors/execution_context_description.cpp @@ -17,17 +17,18 @@ using namespace srsran; thread_local unsigned nof_concurrent_workers = 1; thread_local unsigned worker_index = 0; -unsigned srsran::execution_context::get_nof_concurrent_workers() +unsigned srsran::execution_context::get_current_nof_concurrent_workers() { return nof_concurrent_workers; } -unsigned srsran::execution_context::get_worker_index() +unsigned srsran::execution_context::get_current_worker_index() { return worker_index; } -void srsran::execution_context::set_worker_description(unsigned nof_concurrent_workers_, unsigned worker_index_) +void srsran::execution_context::set_execution_context_description(unsigned nof_concurrent_workers_, + unsigned worker_index_) { srsran_sanity_check(nof_concurrent_workers_ > 0, "Invalid number of workers"); nof_concurrent_workers = nof_concurrent_workers_; diff --git a/lib/support/executors/execution_context_description_setup.h b/lib/support/executors/execution_context_description_setup.h index 6910c45ba7..930a19a49c 100644 --- a/lib/support/executors/execution_context_description_setup.h +++ b/lib/support/executors/execution_context_description_setup.h @@ -11,7 +11,8 @@ namespace srsran { namespace execution_context { -void set_worker_description(unsigned nof_concurrent_workers, unsigned worker_index); +/// Set number of workers and worker index of the current execution context. +void set_execution_context_description(unsigned nof_concurrent_workers, unsigned worker_index); -} +} // namespace execution_context } // namespace srsran \ No newline at end of file diff --git a/lib/support/executors/task_worker_pool.cpp b/lib/support/executors/task_worker_pool.cpp index 15ae11a651..6b9e857abb 100644 --- a/lib/support/executors/task_worker_pool.cpp +++ b/lib/support/executors/task_worker_pool.cpp @@ -22,7 +22,7 @@ std::function worker_task_factory(Queue& queue, unsigned nof_workers, un { return [&queue, nof_workers, worker_idx]() { // setup worker execution context. - execution_context::set_worker_description(nof_workers, worker_idx); + execution_context::set_execution_context_description(nof_workers, worker_idx); // start worker pop loop. while (true) { From a211dce243b41d1c4ed2b62c2ecb4b83d1a0a83e Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 27 Sep 2024 17:31:30 +0200 Subject: [PATCH 160/174] support: add pragma once --- lib/support/executors/execution_context_description_setup.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/support/executors/execution_context_description_setup.h b/lib/support/executors/execution_context_description_setup.h index 930a19a49c..a4675cbcef 100644 --- a/lib/support/executors/execution_context_description_setup.h +++ b/lib/support/executors/execution_context_description_setup.h @@ -8,6 +8,8 @@ * */ +#pragma once + namespace srsran { namespace execution_context { From 9d346d6e5caba5f0451c70f2c882722456a71afb Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 27 Sep 2024 18:04:55 +0200 Subject: [PATCH 161/174] sched: pass cell config to sched metrics handler --- lib/scheduler/config/sched_config_manager.cpp | 29 +++++++++++-------- lib/scheduler/config/sched_config_manager.h | 11 +++---- .../logging/scheduler_metric_handler.cpp | 11 +++---- .../logging/scheduler_metrics_handler.h | 6 +++- lib/scheduler/scheduler_impl.cpp | 15 ++++------ .../test_utils/config_generators.cpp | 5 ++-- .../scheduler/test_utils/config_generators.h | 5 ++++ .../ue_scheduling/fallback_scheduler_test.cpp | 6 ++-- .../ue_scheduling/ue_grid_allocator_test.cpp | 6 ++-- 9 files changed, 52 insertions(+), 42 deletions(-) diff --git a/lib/scheduler/config/sched_config_manager.cpp b/lib/scheduler/config/sched_config_manager.cpp index fb2976c192..98396444d1 100644 --- a/lib/scheduler/config/sched_config_manager.cpp +++ b/lib/scheduler/config/sched_config_manager.cpp @@ -9,6 +9,7 @@ */ #include "sched_config_manager.h" +#include "../logging/scheduler_metrics_handler.h" #include "../logging/scheduler_metrics_ue_configurator.h" #include "srsran/scheduler/config/scheduler_cell_config_validator.h" #include "srsran/scheduler/config/scheduler_ue_config_validator.h" @@ -57,16 +58,17 @@ void ue_config_delete_event::reset() } } -sched_config_manager::sched_config_manager(const scheduler_config& sched_cfg) : +sched_config_manager::sched_config_manager(const scheduler_config& sched_cfg, + scheduler_metrics_handler& metrics_handler_) : expert_params(sched_cfg.expert_params), + metrics_handler(metrics_handler_), config_notifier(sched_cfg.config_notifier), logger(srslog::fetch_basic_logger("SCHED")) { std::fill(ue_to_cell_group_index.begin(), ue_to_cell_group_index.end(), INVALID_DU_CELL_GROUP_INDEX); } -const cell_configuration* sched_config_manager::add_cell(const sched_cell_configuration_request_message& msg, - sched_metrics_ue_configurator& metrics_handler_) +const cell_configuration* sched_config_manager::add_cell(const sched_cell_configuration_request_message& msg) { srsran_assert(msg.cell_index < MAX_NOF_DU_CELLS, "cell index={} is not valid", msg.cell_index); srsran_assert(not added_cells.contains(msg.cell_index), "cell={} already exists", msg.cell_index); @@ -76,7 +78,9 @@ const cell_configuration* sched_config_manager::add_cell(const sched_cell_config srsran_assert(ret.has_value(), "Invalid cell configuration request message. Cause: {}", ret.error().c_str()); added_cells.emplace(msg.cell_index, std::make_unique(expert_params, msg)); - cell_metrics.emplace(msg.cell_index, &metrics_handler_); + + cell_metrics_handler* cell_metrics = metrics_handler.add_cell(*added_cells[msg.cell_index]); + srsran_assert(cell_metrics != nullptr, "Unable to create metrics handler"); return added_cells[msg.cell_index].get(); } @@ -189,17 +193,17 @@ void sched_config_manager::handle_ue_config_complete(du_ue_index_t ue_index, std if (next_cfg != nullptr) { // Creation/Reconfig succeeded. + cell_metrics_handler& cell_metrics = metrics_handler.at(next_cfg->pcell_common_cfg().cell_index); if (ue_cfg_list[ue_index] == nullptr) { // UE creation case. - cell_metrics[next_cfg->pcell_common_cfg().cell_index]->handle_ue_creation( - ue_index, - next_cfg->crnti, - next_cfg->pcell_common_cfg().pci, - next_cfg->pcell_common_cfg().nof_dl_prbs, - next_cfg->pcell_common_cfg().nof_slots_per_frame); + cell_metrics.handle_ue_creation(ue_index, + next_cfg->crnti, + next_cfg->pcell_common_cfg().pci, + next_cfg->pcell_common_cfg().nof_dl_prbs, + next_cfg->pcell_common_cfg().nof_slots_per_frame); } else { // Reconfiguration case. - cell_metrics[next_cfg->pcell_common_cfg().cell_index]->handle_ue_reconfiguration(ue_index); + cell_metrics.handle_ue_reconfiguration(ue_index); } // Stores new UE config and deletes old config. @@ -227,7 +231,8 @@ void sched_config_manager::handle_ue_delete_complete(du_ue_index_t ue_index) ue_cfg_list[ue_index].reset(); // Remove UE from metrics. - cell_metrics[pcell_idx]->handle_ue_deletion(ue_index); + cell_metrics_handler& cell_metrics = metrics_handler.at(pcell_idx); + cell_metrics.handle_ue_deletion(ue_index); // Mark the UE as released. ue_to_cell_group_index[ue_index].store(INVALID_DU_CELL_GROUP_INDEX, std::memory_order_release); diff --git a/lib/scheduler/config/sched_config_manager.h b/lib/scheduler/config/sched_config_manager.h index 683be61c6a..231e9c0517 100644 --- a/lib/scheduler/config/sched_config_manager.h +++ b/lib/scheduler/config/sched_config_manager.h @@ -18,7 +18,7 @@ namespace srsran { class sched_config_manager; -class sched_metrics_ue_configurator; +class scheduler_metrics_handler; /// Event to create/reconfigure a UE in the scheduler. class ue_config_update_event @@ -98,10 +98,9 @@ class sched_ue_configuration_handler class sched_config_manager { public: - sched_config_manager(const scheduler_config& sched_cfg_); + sched_config_manager(const scheduler_config& sched_cfg_, scheduler_metrics_handler& metrics_handler_); - const cell_configuration* add_cell(const sched_cell_configuration_request_message& msg, - sched_metrics_ue_configurator& metrics_handler_); + const cell_configuration* add_cell(const sched_cell_configuration_request_message& msg); ue_config_update_event add_ue(const sched_ue_creation_request_message& cfg_req); @@ -132,15 +131,13 @@ class sched_config_manager void handle_ue_delete_complete(du_ue_index_t ue_index); const scheduler_expert_config expert_params; + scheduler_metrics_handler& metrics_handler; sched_configuration_notifier& config_notifier; srslog::basic_logger& logger; // List of common configs for the scheduler cells. cell_common_configuration_list added_cells; - // List of metrics handlers for each cell. - slotted_id_table cell_metrics; - std::array, MAX_NOF_DU_UES> ue_cfg_list; /// Mapping of UEs to DU Cell Groups. diff --git a/lib/scheduler/logging/scheduler_metric_handler.cpp b/lib/scheduler/logging/scheduler_metric_handler.cpp index e08e37d340..fea92c7e4e 100644 --- a/lib/scheduler/logging/scheduler_metric_handler.cpp +++ b/lib/scheduler/logging/scheduler_metric_handler.cpp @@ -8,6 +8,7 @@ * */ +#include "../config/cell_configuration.h" #include "scheduler_metrics_handler.h" #include "srsran/srslog/srslog.h" @@ -373,14 +374,14 @@ scheduler_metrics_handler::scheduler_metrics_handler(msecs { } -cell_metrics_handler* scheduler_metrics_handler::add_cell(du_cell_index_t cell_idx) +cell_metrics_handler* scheduler_metrics_handler::add_cell(const cell_configuration& cell_cfg) { - if (cells.contains(cell_idx)) { - srslog::fetch_basic_logger("SCHED").warning("Cell={} already exists", cell_idx); + if (cells.contains(cell_cfg.cell_index)) { + srslog::fetch_basic_logger("SCHED").warning("Cell={} already exists", cell_cfg.cell_index); return nullptr; } - cells.emplace(cell_idx, report_period, notifier); + cells.emplace(cell_cfg.cell_index, report_period, notifier); - return &cells[cell_idx]; + return &cells[cell_cfg.cell_index]; } diff --git a/lib/scheduler/logging/scheduler_metrics_handler.h b/lib/scheduler/logging/scheduler_metrics_handler.h index ee53057956..3f71363af0 100644 --- a/lib/scheduler/logging/scheduler_metrics_handler.h +++ b/lib/scheduler/logging/scheduler_metrics_handler.h @@ -20,6 +20,8 @@ namespace srsran { +class cell_configuration; + ///\brief Handler of scheduler slot metrics for a given cell. class cell_metrics_handler final : public harq_timeout_handler, public sched_metrics_ue_configurator { @@ -167,7 +169,9 @@ class scheduler_metrics_handler /// \brief Creates a scheduler metrics handler. In case the metrics_report_period is zero, no metrics are reported. explicit scheduler_metrics_handler(msecs metrics_report_period, scheduler_metrics_notifier& notifier); - cell_metrics_handler* add_cell(du_cell_index_t cell_idx); + cell_metrics_handler* add_cell(const cell_configuration& cell_cfg); + + cell_metrics_handler& at(du_cell_index_t cell_idx) { return cells[cell_idx]; } private: scheduler_metrics_notifier& notifier; diff --git a/lib/scheduler/scheduler_impl.cpp b/lib/scheduler/scheduler_impl.cpp index 05fe931ea7..3a2bcfa981 100644 --- a/lib/scheduler/scheduler_impl.cpp +++ b/lib/scheduler/scheduler_impl.cpp @@ -18,18 +18,13 @@ scheduler_impl::scheduler_impl(const scheduler_config& sched_cfg_) : expert_params(sched_cfg_.expert_params), logger(srslog::fetch_basic_logger("SCHED")), metrics(expert_params.metrics_report_period, sched_cfg_.metrics_notifier), - cfg_mng(sched_cfg_) + cfg_mng(sched_cfg_, metrics) { } bool scheduler_impl::handle_cell_configuration_request(const sched_cell_configuration_request_message& msg) { - cell_metrics_handler* cell_metrics = metrics.add_cell(msg.cell_index); - if (cell_metrics == nullptr) { - return false; - } - - const cell_configuration* cell_cfg = cfg_mng.add_cell(msg, *cell_metrics); + const cell_configuration* cell_cfg = cfg_mng.add_cell(msg); if (cell_cfg == nullptr) { return false; } @@ -41,9 +36,9 @@ bool scheduler_impl::handle_cell_configuration_request(const sched_cell_configur } // Create a new cell scheduler instance. - cells.emplace( - msg.cell_index, - std::make_unique(expert_params, msg, *cell_cfg, *groups[msg.cell_group_index], *cell_metrics)); + cells.emplace(msg.cell_index, + std::make_unique( + expert_params, msg, *cell_cfg, *groups[msg.cell_group_index], metrics.at(msg.cell_index))); return true; } diff --git a/tests/unittests/scheduler/test_utils/config_generators.cpp b/tests/unittests/scheduler/test_utils/config_generators.cpp index 2a2bef0e43..16246ed4bb 100644 --- a/tests/unittests/scheduler/test_utils/config_generators.cpp +++ b/tests/unittests/scheduler/test_utils/config_generators.cpp @@ -52,7 +52,8 @@ test_sched_config_manager::test_sched_config_manager(const cell_config_builder_p cfg_notifier(std::make_unique()), metric_notifier(std::make_unique()), ue_metrics_configurator(std::make_unique()), - cfg_mng(scheduler_config{expert_cfg, *cfg_notifier, *metric_notifier}) + metrics_handler(std::chrono::milliseconds{1000}, *metric_notifier), + cfg_mng(scheduler_config{expert_cfg, *cfg_notifier, *metric_notifier}, metrics_handler) { default_cell_req = test_helpers::make_default_sched_cell_configuration_request(builder_params); default_ue_req = test_helpers::create_default_sched_ue_creation_request(builder_params, {lcid_t::LCID_MIN_DRB}); @@ -62,7 +63,7 @@ test_sched_config_manager::~test_sched_config_manager() {} const cell_configuration* test_sched_config_manager::add_cell(const sched_cell_configuration_request_message& msg) { - return cfg_mng.add_cell(msg, *ue_metrics_configurator); + return cfg_mng.add_cell(msg); } const ue_configuration* test_sched_config_manager::add_ue(const sched_ue_creation_request_message& cfg_req) diff --git a/tests/unittests/scheduler/test_utils/config_generators.h b/tests/unittests/scheduler/test_utils/config_generators.h index d9c5211a3b..387eb6ce28 100644 --- a/tests/unittests/scheduler/test_utils/config_generators.h +++ b/tests/unittests/scheduler/test_utils/config_generators.h @@ -12,6 +12,7 @@ #include "lib/du/du_high/du_manager/converters/scheduler_configuration_helpers.h" #include "lib/scheduler/config/sched_config_manager.h" +#include "lib/scheduler/logging/scheduler_metrics_handler.h" #include "srsran/du/du_cell_config_helpers.h" #include "srsran/ran/duplex_mode.h" #include "srsran/ran/pucch/pucch_info.h" @@ -24,6 +25,9 @@ #include "srsran/support/test_utils.h" namespace srsran { + +class sched_metrics_ue_configurator; + namespace test_helpers { inline sched_cell_configuration_request_message @@ -341,6 +345,7 @@ class test_sched_config_manager std::unique_ptr cfg_notifier; std::unique_ptr metric_notifier; std::unique_ptr ue_metrics_configurator; + scheduler_metrics_handler metrics_handler; sched_cell_configuration_request_message default_cell_req; sched_ue_creation_request_message default_ue_req; diff --git a/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp b/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp index 41b9366d08..ccf2c16d6e 100644 --- a/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp +++ b/tests/unittests/scheduler/ue_scheduling/fallback_scheduler_test.cpp @@ -10,6 +10,7 @@ #include "lib/scheduler/common_scheduling/csi_rs_scheduler.h" #include "lib/scheduler/config/sched_config_manager.h" +#include "lib/scheduler/logging/scheduler_metrics_handler.h" #include "lib/scheduler/logging/scheduler_result_logger.h" #include "lib/scheduler/pdcch_scheduling/pdcch_resource_allocator_impl.h" #include "lib/scheduler/pucch_scheduling/pucch_allocator_impl.h" @@ -80,8 +81,9 @@ struct test_bench { scheduler_harq_timeout_dummy_handler harq_timeout_handler; scheduler_ue_metrics_dummy_configurator metrics_ue_handler; cell_config_builder_params builder_params; + scheduler_metrics_handler metrics{std::chrono::milliseconds{0}, metrics_notif}; - sched_config_manager cfg_mng{scheduler_config{sched_cfg, dummy_notif, metrics_notif}}; + sched_config_manager cfg_mng{scheduler_config{sched_cfg, dummy_notif, metrics_notif}, metrics}; const cell_configuration& cell_cfg; cell_resource_allocator res_grid{cell_cfg}; @@ -101,7 +103,7 @@ struct test_bench { const sched_cell_configuration_request_message& cell_req) : sched_cfg{sched_cfg_}, builder_params{builder_params_}, - cell_cfg{*[&]() { return cfg_mng.add_cell(cell_req, metrics_ue_handler); }()}, + cell_cfg{*[&]() { return cfg_mng.add_cell(cell_req); }()}, ue_alloc(expert_cfg, ue_db, srslog::fetch_basic_logger("SCHED", true)), fallback_sched(expert_cfg, cell_cfg, pdcch_sch, pucch_alloc, ue_db), csi_rs_sched(cell_cfg) diff --git a/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp b/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp index 60b77e5c07..fe36eba1e3 100644 --- a/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp +++ b/tests/unittests/scheduler/ue_scheduling/ue_grid_allocator_test.cpp @@ -37,8 +37,7 @@ class ue_grid_allocator_tester : public ::testing::TestWithParam GetParam() == duplex_mode::FDD ? subcarrier_spacing::kHz15 : subcarrier_spacing::kHz30; cfg_builder_params.band = band_helper::get_band_from_dl_arfcn(cfg_builder_params.dl_f_ref_arfcn); cfg_builder_params.channel_bw_mhz = bs_channel_bandwidth::MHz20; - auto* cfg = cfg_mng.add_cell(test_helpers::make_default_sched_cell_configuration_request(cfg_builder_params), - metrics_ue_handler); + auto* cfg = cfg_mng.add_cell(test_helpers::make_default_sched_cell_configuration_request(cfg_builder_params)); srsran_assert(cfg != nullptr, "Cell configuration failed"); return cfg; }()), @@ -124,9 +123,10 @@ class ue_grid_allocator_tester : public ::testing::TestWithParam scheduler_ue_metrics_dummy_notifier metrics_notif; scheduler_ue_metrics_dummy_configurator metrics_ue_handler; scheduler_harq_timeout_dummy_handler harq_timeout_handler; + scheduler_metrics_handler metrics{std::chrono::milliseconds{0}, metrics_notif}; cell_config_builder_params cfg_builder_params; - sched_config_manager cfg_mng{scheduler_config{sched_cfg, mac_notif, metrics_notif}}; + sched_config_manager cfg_mng{scheduler_config{sched_cfg, mac_notif, metrics_notif}, metrics}; const cell_configuration& cell_cfg; cell_harq_manager cell_harqs{MAX_NOF_DU_UES, From 7f1bca9e7d9bd1fd66c2be8903785932060afa8f Mon Sep 17 00:00:00 2001 From: asaezper Date: Fri, 27 Sep 2024 14:16:25 +0200 Subject: [PATCH 162/174] ci: use ims tests with hp sdr --- .gitlab/ci/e2e.yml | 2 +- .gitlab/ci/e2e/retina_request_android_callbox.yml | 12 ++++++------ tests/e2e/tests/ping.py | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitlab/ci/e2e.yml b/.gitlab/ci/e2e.yml index 2619305b08..aa887c2f26 100644 --- a/.gitlab/ci/e2e.yml +++ b/.gitlab/ci/e2e.yml @@ -565,7 +565,7 @@ android b200: artifacts: true - *retina-needs -android b200 IMS: +android IMS: stage: rf extends: .e2e-run variables: diff --git a/.gitlab/ci/e2e/retina_request_android_callbox.yml b/.gitlab/ci/e2e/retina_request_android_callbox.yml index 482084e174..10275571f5 100644 --- a/.gitlab/ci/e2e/retina_request_android_callbox.yml +++ b/.gitlab/ci/e2e/retina_request_android_callbox.yml @@ -27,21 +27,21 @@ - name: srs-gnb type: gnb image: ${RETINA_REGISTRY_PREFIX}/srsgnb:${RETINA_VERSION} - host_network: true requirements: arch: amd64 cpu: - requests: 6 - limits: 6 + requests: 12 + limits: 12 memory: - requests: "10G" - limits: "10G" + requests: "20G" + limits: "20G" ephemeral-storage: requests: "6G" limits: "6G" + taints: ["purpose=manual-testing"] resources: - type: sdr - model: b200 + model: x300 environment: - PATH: ${PATH}:/builds/softwareradiosystems/srsgnb/build/apps/gnb shared_files: diff --git a/tests/e2e/tests/ping.py b/tests/e2e/tests/ping.py index 4972d3efa1..b3b39121ab 100644 --- a/tests/e2e/tests/ping.py +++ b/tests/e2e/tests/ping.py @@ -84,9 +84,9 @@ def test_android( @mark.parametrize( "ims_mode", ( - param(""), - param("enabled"), - param("not_registering"), + param("", id="ims:disabled"), + param("enabled", id="ims:%s"), + param("not_registering", id="ims:%s"), ), ) @mark.parametrize( @@ -99,7 +99,7 @@ def test_android( @mark.android @mark.flaky( reruns=2, - only_rerun=["failed to start", "Exception calling application", "Attach timeout reached", "Some packages got lost"], + only_rerun=["failed to start", "Exception calling application"], ) # pylint: disable=too-many-arguments,too-many-positional-arguments def test_android_ims( From 2817c8873aa5714f4dd974c7bd45a8c4c8aafeab Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 6 Sep 2024 17:26:18 +0200 Subject: [PATCH 163/174] du: functions to compute srs resource cell list Signed-off-by: Carlo Galiotto --- .../srs_resource_generator.cpp | 78 +++++++++++++++++++ .../srs_resource_generator.h | 41 ++++++++++ 2 files changed, 119 insertions(+) create mode 100644 lib/du_manager/ran_resource_management/srs_resource_generator.cpp create mode 100644 lib/du_manager/ran_resource_management/srs_resource_generator.h diff --git a/lib/du_manager/ran_resource_management/srs_resource_generator.cpp b/lib/du_manager/ran_resource_management/srs_resource_generator.cpp new file mode 100644 index 0000000000..a350621784 --- /dev/null +++ b/lib/du_manager/ran_resource_management/srs_resource_generator.cpp @@ -0,0 +1,78 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srs_resource_generator.h" + +using namespace srsran; +using namespace srs_du; + +std::vector srsran::srs_du::generate_cell_srs_list(const du_cell_config& du_cell_cfg) +{ + std::vector srs_res_list; + // Compute the available TX comb offsets. \ref tx_comb_cyclic_shift, in \c srs_config::srs_resource::tx_comb_params. + std::vector tx_comb_offsets = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 + ? std::vector{0U, 1U} + : std::vector{0U, 1U, 2U, 3U}; + + // Compute the available Cyclic Shifts. + const unsigned max_cs = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 ? 8U : 12U; + const unsigned cs_step = max_cs / static_cast(du_cell_cfg.srs_cfg.cyclic_shift_reuse_factor); + std::vector cs_values; + for (unsigned cs = 0; cs < max_cs; cs += cs_step) { + cs_values.push_back(cs); + } + + // Compute the available Sequence IDs. + // NOTE: we only consider the number of orthogonal sequences that can be generated, as per TS 38.211, + // Section 6.4.1.4.2, which is 30. + constexpr unsigned max_seq_id_values = 30U; + const unsigned seq_id_step = max_seq_id_values / static_cast(du_cell_cfg.srs_cfg.sequence_id_reuse_factor); + std::vector seq_id_values; + for (unsigned seq_id = 0; seq_id < max_seq_id_values; seq_id += seq_id_step) { + seq_id_values.push_back(static_cast(du_cell_cfg.pci) + seq_id); + } + + // Find the first symbol within the UL slot (considering all options FDD, TDD pattern 1 and TDD pattern 2) where the + // SRS resource can be placed. + unsigned starting_sym = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.to_uint(); + if (du_cell_cfg.tdd_ul_dl_cfg_common.has_value()) { + const auto& tdd_cfg = du_cell_cfg.tdd_ul_dl_cfg_common.value(); + starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern1.nof_ul_symbols); + if (tdd_cfg.pattern2.has_value()) { + starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern2.value().nof_ul_symbols); + } + } + // The number of SRS symbols cannot be larger than 6. + starting_sym = std::max(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.max()); + + // We use the counter to define the cell resource ID. + unsigned srs_res_cnt = 0; + for (unsigned sym_start = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - static_cast(du_cell_cfg.srs_cfg.nof_symbols); + sym_start >= starting_sym; + sym_start -= static_cast(du_cell_cfg.srs_cfg.nof_symbols)) { + const ofdm_symbol_range srs_res_symbols{sym_start, + sym_start + static_cast(du_cell_cfg.srs_cfg.nof_symbols)}; + for (auto tx_comb_offset : tx_comb_offsets) { + for (auto cs : cs_values) { + for (auto seq_id : seq_id_values) { + du_srs_resource srs_res; + srs_res.cell_res_id = srs_res_cnt; + srs_res.tx_comb_offset = tx_comb_offset; + srs_res.symbols = srs_res_symbols; + srs_res.sequence_id = seq_id; + srs_res.cs = cs; + srs_res_list.push_back(srs_res); + ++srs_res_cnt; + } + } + } + } + return srs_res_list; +} diff --git a/lib/du_manager/ran_resource_management/srs_resource_generator.h b/lib/du_manager/ran_resource_management/srs_resource_generator.h new file mode 100644 index 0000000000..6390e0a6d8 --- /dev/null +++ b/lib/du_manager/ran_resource_management/srs_resource_generator.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "du_ue_resource_config.h" + +namespace srsran::srs_du { + +/// Contains the parameters for the SRS resources of a cell. +struct du_srs_resource { + /// Id of the cell SRS resource. + unsigned cell_res_id; + /// Comb offset, as per \c transmissionComb, \c SRS-Resource, \c SRS-Config, TS 38.331. + bounded_integer tx_comb_offset; + /// OFDM symbol range where the SRS resource is placed. + ofdm_symbol_range symbols; + /// \c freqDomainPosition, as per \c SRS-Resource, \c SRS-Config, TS 38.331. + unsigned freq_dom_position = 0; + /// \c sequenceId, as per \c SRS-Resource, \c SRS-Config, TS 38.331. + unsigned sequence_id = 0; + /// Cyclic shift, as per \c transmissionComb, \c SRS-Resource, \c SRS-Config, TS 38.331. + unsigned cs = 0; +}; + +/// \brief Generates the list of orthogonal SRS resources available in a cell. +/// The resources of this cells are meant to be used by the UEs; the same resources can be reused by different UEs over +/// different slots. Note that this function does not allocate the resources to the UEs, it only creates the cell +/// resource list. +/// \param[in] du_cell_cfg Cell configuration parameters. +/// \return List of orthogonal SRS resources. +std::vector generate_cell_srs_list(const du_cell_config& du_cell_cfg); + +} // namespace srsran::srs_du From 9eab2162970ef3166a210262967568acd826e49c Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 29 Aug 2024 17:57:22 +0200 Subject: [PATCH 164/174] du: first version of DU SRS resource manager Signed-off-by: Carlo Galiotto --- .../ran_resource_management/CMakeLists.txt | 1 + .../du_ran_resource_manager_impl.cpp | 5 +- .../du_ran_resource_manager_impl.h | 3 + .../du_srs_resource_manager.cpp | 245 ++++++++++++++++++ .../du_srs_resource_manager.h | 103 ++++++++ .../srs_resource_generator.cpp | 78 ------ .../srs_resource_generator.h | 41 --- 7 files changed, 355 insertions(+), 121 deletions(-) create mode 100644 lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp create mode 100644 lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h delete mode 100644 lib/du_manager/ran_resource_management/srs_resource_generator.cpp delete mode 100644 lib/du_manager/ran_resource_management/srs_resource_generator.h diff --git a/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt b/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt index 88531936c6..04980a4aed 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt +++ b/lib/du/du_high/du_manager/ran_resource_management/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(du_resource_manager du_bearer_resource_manager.cpp du_pucch_resource_manager.cpp du_ran_resource_manager_impl.cpp + du_srs_resource_manager.cpp pucch_resource_generator.cpp srs_resource_generator.cpp ue_capability_manager.cpp) diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp index 5f29f08f91..f217e60866 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp @@ -47,7 +47,8 @@ du_ran_resource_manager_impl::du_ran_resource_manager_impl(span(cell_cfg_list)) { } @@ -164,7 +165,7 @@ error_type du_ran_resource_manager_impl::allocate_cell_resources(du ue_res.cell_group.pcg_cfg.pdsch_harq_codebook = pdsch_harq_ack_codebook::dynamic; if (not pucch_res_mng.alloc_resources(ue_res.cell_group)) { - // Deallocate dedicated Search Spaces. + // Deallocate previously allocated SRS + dedicated Search Spaces. ue_res.cell_group.cells[0].serv_cell_cfg.init_dl_bwp.pdcch_cfg->search_spaces.clear(); return make_unexpected(fmt::format("Unable to allocate dedicated PUCCH resources for cell={}", cell_index)); } diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h index c4f0f65422..fa88c3ee69 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h +++ b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.h @@ -13,6 +13,7 @@ #include "du_bearer_resource_manager.h" #include "du_pucch_resource_manager.h" #include "du_ran_resource_manager.h" +#include "du_srs_resource_manager.h" #include "ue_capability_manager.h" #include "srsran/ran/qos/five_qi.h" @@ -107,6 +108,8 @@ class du_ran_resource_manager_impl : public du_ran_resource_manager /// Allocator of UE bearer resources. du_bearer_resource_manager bearer_res_mng; + + std::unique_ptr srs_res_mng; }; } // namespace srs_du diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp new file mode 100644 index 0000000000..7e74c8abba --- /dev/null +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -0,0 +1,245 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "du_srs_resource_manager.h" +#include "du_ue_resource_config.h" +#include "srsran/ran/srs/srs_bandwidth_configuration.h" + +using namespace srsran; +using namespace srs_du; + +static std::optional compute_srs_bw_param(unsigned nof_ul_rbs) +{ + // Iterate over Table 6.4.1.4.3-1, TS 38.211, and find the first \f$C_{SRS}\f$ value that provides the + // greatest \f$m_{SRS,0}\f$ such that it is less than or equal to number of UL RBs. + + // As per Table 6.4.1.4.3-1, TS 38.211, the maximum value of \f$C_{SRS}\f$ is 63. + constexpr unsigned max_non_valid_c_srs = 64; + constexpr uint8_t b_srs_0 = 0; + for (uint8_t c_srs = 0; c_srs != max_non_valid_c_srs; c_srs++) { + auto srs_params = srs_configuration_get(c_srs, b_srs_0); + srsran_assert(srs_params.has_value(), "The SRS is not valid"); + + if (c_srs == 0 and srs_params.value().m_srs > nof_ul_rbs) { + srsran_assertion_failure("C_SRS is not compatible with the number of UL RBs"); + return std::nullopt; + } + if (srs_params.value().m_srs == nof_ul_rbs) { + return c_srs; + } + if (srs_params.value().m_srs > nof_ul_rbs) { + return c_srs - 1; + } + } + return max_non_valid_c_srs - 1; +} + +// Helper that returns the frequency shift value for the SRS; the value is computed in such a way that the SRS resources +// are placed at the center of the band. +static unsigned compute_freq_shift(unsigned c_srs, unsigned nof_ul_rbs) +{ + // As per Section 6.4.1.4.3, the parameter \f$C_{SRS}\f$ = 0 provides the bandwidth of the SRS resources. + constexpr uint8_t b_srs_0 = 0; + std::optional srs_params = srs_configuration_get(c_srs, b_srs_0); + srsran_sanity_check(srs_params.has_value() and nof_ul_rbs >= srs_params.value().m_srs, + "The SRS configuration is not valid"); + + return (nof_ul_rbs - srs_params.value().m_srs) / 2; +} + +static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0; +} + +static bool is_partually_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0 and + srsran::get_active_tdd_dl_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != + NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; +} + +du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell_cfg_list_) : + cells(cell_cfg_list_.begin(), cell_cfg_list_.end()) +{ + for (auto& cell : cells) { + std::optional c_srs = + compute_srs_bw_param(cell.cell_cfg.ul_cfg_common.init_ul_bwp.generic_params.crbs.length()).value(); + srsran_assert(c_srs.has_value(), "SRS parameters didn't provide a valid C_SRS value"); + cell.srs_common_params.c_srs = c_srs.value(); + std::optional freq_shift = + compute_freq_shift(c_srs.value(), cell.cell_cfg.ul_cfg_common.init_ul_bwp.generic_params.crbs.length()); + srsran_assert(freq_shift.has_value(), "SRS parameters didn't provide a valid freq_shift value"); + cell.srs_common_params.freq_shift = freq_shift.value(); + + cell.cell_srs_res_list = generate_cell_srs_list(cell.cell_cfg); + + const unsigned srs_period_slots = static_cast(cell.cell_cfg.srs_cfg.srs_period.value()); + cell.slot_resource_cnt.reserve(srs_period_slots); + + for (unsigned offset = 0; offset != srs_period_slots; ++offset) { + unsigned offset_res_cnt = 0U; + for (auto& res : cell.cell_srs_res_list) { + // Handle TDD and FDD configurations separately, as we treat partially-UL slots differently from fully-UL slots. + if (cell_cfg_list_[0].tdd_ul_dl_cfg_common.has_value()) { + // Verify whether the offset maps to a partially- or fully-UL slot. + if (not is_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { + continue; + } + // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the slot. + if (is_partually_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { + // TODO: Fix check for pattern 2. + if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - + cell_cfg_list_[0].tdd_ul_dl_cfg_common.value().pattern1.nof_ul_symbols) { + continue; + } + } + // This is the fully-UL slot case: check if the SRS can be placed in the UL symbols of the slot. + else if (res.symbols.start() < + NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell.cell_cfg.srs_cfg.max_nof_symbols.to_uint()) { + continue; + } + } + // FDD case. + else { + if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell.cell_cfg.srs_cfg.max_nof_symbols.to_uint()) { + continue; + } + } + cell.srs_res_offset_free_list.push_back({res.cell_res_id, offset}); + ++offset_res_cnt; + } + cell.slot_resource_cnt.push_back({0U, offset_res_cnt}); + } + } +} + +bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) +{ + // Allocation of SR PUCCH offset. + cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( + cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].default_srs_cfg); + srs_config& ue_srs_cfg = cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + auto& free_srs_list = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_res_offset_free_list; + + // Verify where there are SRS resources to allocate a new UE. + if (free_srs_list.empty()) { + return false; + } + + // Find the best resource ID and offset for this UE. + auto srs_res_id_offset = cells[0].find_optimal_ue_srs_resource(); + + if (srs_res_id_offset == free_srs_list.end()) { + return false; + } + + const auto& du_res_it = cells[0].get_du_srs_res_cfg(srs_res_id_offset->first); + + if (du_res_it == cells[0].cell_srs_res_list.end()) { + return false; + } + + const auto& du_res = *du_res_it; + + // Update the SRS configuration with the parameters that are specific to this resource and for this UE. + auto& only_ue_srs_res = ue_srs_cfg.srs_res_list.front(); + const unsigned srs_offset = srs_res_id_offset->second; + // NOTE: given that there is only 1 SRS resource per UE, we can assume that the SRS resource ID is 0. + only_ue_srs_res.id.cell_res_id = du_res.cell_res_id; + only_ue_srs_res.id.ue_res_id = static_cast(0U); + only_ue_srs_res.periodicity_and_offset.value().offset = srs_offset; + only_ue_srs_res.tx_comb.tx_comb_offset = du_res.tx_comb_offset.to_uint(); + only_ue_srs_res.freq_domain_pos = du_res.freq_dom_position; + only_ue_srs_res.res_mapping.start_pos = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_res.symbols.start() - 1; + only_ue_srs_res.res_mapping.nof_symb = static_cast(du_res.symbols.length()); + only_ue_srs_res.sequence_id = du_res.sequence_id; + + // Update the SRS configuration with the parameters that are common to the cell. + only_ue_srs_res.freq_hop.c_srs = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.c_srs; + only_ue_srs_res.freq_domain_shift = + cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.freq_shift; + + // Update the SRS resource set with the SRS id. + ue_srs_cfg.srs_res_set_list.front().srs_res_id_list.front() = only_ue_srs_res.id.ue_res_id; + + // Remove the allocated SRS resource from the free list. + free_srs_list.erase(srs_res_id_offset); + + // Update the used_not_full slot vector. + ++cells[0].slot_resource_cnt[srs_offset].first; + + return true; +} + +std::vector>::const_iterator +du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() +{ + // The weights assigned here can be set to any value, as long as: + // - symbol_weight_base is greater than 0; + // - reuse_slot_discount less than symbol_weight_base; + // - max_weight is > symbol_weight_base * (srs_builder_params::max_nof_symbols / srs_builder_params::nof_symbols). + static constexpr unsigned max_weight = 100U; + static constexpr unsigned symbol_weight_base = 10U; + + const auto weight_function = [&](const pair_res_id_offset& srs_res) { + if (cell_cfg.tdd_ul_dl_cfg_common.has_value() and + is_partually_ul_slot(srs_res.second, cell_cfg.tdd_ul_dl_cfg_common.value())) { + return 0U; + } + + // SRS res config. + const auto srs_res_cfg_it = get_du_srs_res_cfg(srs_res.first); + + if (srs_res_cfg_it == cell_srs_res_list.end()) { + return max_weight; + } + + // Give priority to the last symbols within a slot. This reduces the space used for the SRS in a slot. + const unsigned symb_weight = + (NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res_cfg_it->symbols.start()) * symbol_weight_base; + + // We consider a discount if the offset is already used but not full; this way, we give an incentive to the SRS + // resources not to be allocated on a new slot, to avoid taking PUSCH symbols on a new slot. + const unsigned reuse_slot_discount = offset_used_not_full(srs_res.second) ? symbol_weight_base / 2U : 0U; + + return symb_weight - reuse_slot_discount; + }; + + auto optimal_res_it = std::min_element( + srs_res_offset_free_list.begin(), + srs_res_offset_free_list.end(), + [&weight_function](const std::pair& lhs, const std::pair& rhs) { + return weight_function(lhs) < weight_function(rhs); + }); + + return optimal_res_it; +} + +void du_srs_policy_max_ul_th::dealloc_resources(cell_group_config& cell_grp_cfg) +{ + if (not cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()) { + return; + } + + const auto& ue_srs_cfg = cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + auto& free_srs_list = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_res_offset_free_list; + + for (const auto& srs_res : ue_srs_cfg.srs_res_list) { + const unsigned offset_to_deallocate = srs_res.periodicity_and_offset.value().offset; + free_srs_list.push_back({srs_res.id.cell_res_id, offset_to_deallocate}); + + // Update the used_not_full slot vector. + srsran_assert(cells[0].slot_resource_cnt[offset_to_deallocate].first != 0, "The offset is expected to be non-zero"); + --cells[0].slot_resource_cnt[offset_to_deallocate].first; + } +} diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h new file mode 100644 index 0000000000..2200ab196f --- /dev/null +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h @@ -0,0 +1,103 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#pragma once + +#include "srs_resource_generator.h" +#include "srsran/adt/optional.h" +#include "srsran/du/du_cell_config.h" +#include "srsran/ran/srs/srs_configuration.h" + +namespace srsran { +namespace srs_du { + +struct cell_group_config; + +/// This abstract class defines the methods that the DU SRS resource manager must implement. The implementation of this +/// class defines different policies for the SRS allocation. +class du_srs_resource_manager +{ +public: + virtual ~du_srs_resource_manager() = default; + + /// \brief Allocate SRS resources for a given UE. The resources are stored in the UE's cell group config. + /// The function allocates the UE the resources from a common pool. + /// \return true if allocation was successful. + virtual bool alloc_resources(cell_group_config& cell_grp_cfg) = 0; + + /// \brief Deallocate the SRS resources for a given UE and return the used resource to the common pool. + virtual void dealloc_resources(cell_group_config& cell_grp_cfg) = 0; +}; + +/// This class implements the MAX UL throughput policy for the SRS allocation. The SRS resources are allocated to +/// minimize the number of slots that contains the SRS resources; furthermore, within a given slot, the SRS resources +/// are allocated to minimize the number of symbols that are used for SRS. The drawback of this policy is that it can +/// increase the inter slot SRS interference among different UEs. +class du_srs_policy_max_ul_th : public du_srs_resource_manager +{ +public: + explicit du_srs_policy_max_ul_th(span cell_cfg_list_); + + bool alloc_resources(cell_group_config& cell_grp_cfg) override; + + void dealloc_resources(cell_group_config& cell_grp_cfg) override; + +private: + struct cell_context { + cell_context(const du_cell_config& cfg) : + cell_cfg(cfg), default_srs_cfg(cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.value()){}; + + using pair_res_id_offset = std::pair; + + // Returns the DU SRS resource with the given cell resource ID from the cell list of resources. + std::vector::const_iterator get_du_srs_res_cfg(unsigned cell_res_id) + { + return std::find_if(cell_srs_res_list.begin(), + cell_srs_res_list.end(), + [cell_res_id](const du_srs_resource& res) { return res.cell_res_id == cell_res_id; }); + } + + // Returns the best SRS resource ID and offset for this UE, according to the policy defined in this class. + std::vector::const_iterator find_optimal_ue_srs_resource(); + + // Check if this SRS offset has already some SRS resources allocated, but can still host more. + bool offset_used_not_full(unsigned offset) const + { + srsran_assert(offset < slot_resource_cnt.size(), "Offset out of range"); + return slot_resource_cnt[offset].first != 0 and + slot_resource_cnt[offset].first < slot_resource_cnt[offset].second; + } + + // Parameters that are common to all cell SRS resources. + struct srs_cell_common { + unsigned c_srs; + unsigned freq_shift; + }; + + using pair_cnt_max = std::pair; + + const du_cell_config& cell_cfg; + const srs_config default_srs_cfg; + srs_cell_common srs_common_params; + // List of all SRS resources available to the cell; these resources can be allocated over to different UEs over + // different offsets. + std::vector cell_srs_res_list; + // List of SRS resource ID and offset that can be allocated to the cell's UEs. + std::vector srs_res_offset_free_list; + // Counter of how many SRS resources (current counter, max_counter) that can be allocated in the same slot (offset). + std::vector slot_resource_cnt; + }; + + // Contains the resources for the different cells of the DU. + static_vector cells; +}; + +} // namespace srs_du +} // namespace srsran diff --git a/lib/du_manager/ran_resource_management/srs_resource_generator.cpp b/lib/du_manager/ran_resource_management/srs_resource_generator.cpp deleted file mode 100644 index a350621784..0000000000 --- a/lib/du_manager/ran_resource_management/srs_resource_generator.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * Copyright 2021-2024 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#include "srs_resource_generator.h" - -using namespace srsran; -using namespace srs_du; - -std::vector srsran::srs_du::generate_cell_srs_list(const du_cell_config& du_cell_cfg) -{ - std::vector srs_res_list; - // Compute the available TX comb offsets. \ref tx_comb_cyclic_shift, in \c srs_config::srs_resource::tx_comb_params. - std::vector tx_comb_offsets = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 - ? std::vector{0U, 1U} - : std::vector{0U, 1U, 2U, 3U}; - - // Compute the available Cyclic Shifts. - const unsigned max_cs = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 ? 8U : 12U; - const unsigned cs_step = max_cs / static_cast(du_cell_cfg.srs_cfg.cyclic_shift_reuse_factor); - std::vector cs_values; - for (unsigned cs = 0; cs < max_cs; cs += cs_step) { - cs_values.push_back(cs); - } - - // Compute the available Sequence IDs. - // NOTE: we only consider the number of orthogonal sequences that can be generated, as per TS 38.211, - // Section 6.4.1.4.2, which is 30. - constexpr unsigned max_seq_id_values = 30U; - const unsigned seq_id_step = max_seq_id_values / static_cast(du_cell_cfg.srs_cfg.sequence_id_reuse_factor); - std::vector seq_id_values; - for (unsigned seq_id = 0; seq_id < max_seq_id_values; seq_id += seq_id_step) { - seq_id_values.push_back(static_cast(du_cell_cfg.pci) + seq_id); - } - - // Find the first symbol within the UL slot (considering all options FDD, TDD pattern 1 and TDD pattern 2) where the - // SRS resource can be placed. - unsigned starting_sym = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.to_uint(); - if (du_cell_cfg.tdd_ul_dl_cfg_common.has_value()) { - const auto& tdd_cfg = du_cell_cfg.tdd_ul_dl_cfg_common.value(); - starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern1.nof_ul_symbols); - if (tdd_cfg.pattern2.has_value()) { - starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern2.value().nof_ul_symbols); - } - } - // The number of SRS symbols cannot be larger than 6. - starting_sym = std::max(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.max()); - - // We use the counter to define the cell resource ID. - unsigned srs_res_cnt = 0; - for (unsigned sym_start = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - static_cast(du_cell_cfg.srs_cfg.nof_symbols); - sym_start >= starting_sym; - sym_start -= static_cast(du_cell_cfg.srs_cfg.nof_symbols)) { - const ofdm_symbol_range srs_res_symbols{sym_start, - sym_start + static_cast(du_cell_cfg.srs_cfg.nof_symbols)}; - for (auto tx_comb_offset : tx_comb_offsets) { - for (auto cs : cs_values) { - for (auto seq_id : seq_id_values) { - du_srs_resource srs_res; - srs_res.cell_res_id = srs_res_cnt; - srs_res.tx_comb_offset = tx_comb_offset; - srs_res.symbols = srs_res_symbols; - srs_res.sequence_id = seq_id; - srs_res.cs = cs; - srs_res_list.push_back(srs_res); - ++srs_res_cnt; - } - } - } - } - return srs_res_list; -} diff --git a/lib/du_manager/ran_resource_management/srs_resource_generator.h b/lib/du_manager/ran_resource_management/srs_resource_generator.h deleted file mode 100644 index 6390e0a6d8..0000000000 --- a/lib/du_manager/ran_resource_management/srs_resource_generator.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Copyright 2021-2024 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#pragma once - -#include "du_ue_resource_config.h" - -namespace srsran::srs_du { - -/// Contains the parameters for the SRS resources of a cell. -struct du_srs_resource { - /// Id of the cell SRS resource. - unsigned cell_res_id; - /// Comb offset, as per \c transmissionComb, \c SRS-Resource, \c SRS-Config, TS 38.331. - bounded_integer tx_comb_offset; - /// OFDM symbol range where the SRS resource is placed. - ofdm_symbol_range symbols; - /// \c freqDomainPosition, as per \c SRS-Resource, \c SRS-Config, TS 38.331. - unsigned freq_dom_position = 0; - /// \c sequenceId, as per \c SRS-Resource, \c SRS-Config, TS 38.331. - unsigned sequence_id = 0; - /// Cyclic shift, as per \c transmissionComb, \c SRS-Resource, \c SRS-Config, TS 38.331. - unsigned cs = 0; -}; - -/// \brief Generates the list of orthogonal SRS resources available in a cell. -/// The resources of this cells are meant to be used by the UEs; the same resources can be reused by different UEs over -/// different slots. Note that this function does not allocate the resources to the UEs, it only creates the cell -/// resource list. -/// \param[in] du_cell_cfg Cell configuration parameters. -/// \return List of orthogonal SRS resources. -std::vector generate_cell_srs_list(const du_cell_config& du_cell_cfg); - -} // namespace srsran::srs_du From 5028ce10ca43eb8ea6b793ab14aadef1950aee9c Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Wed, 4 Sep 2024 10:49:17 +0200 Subject: [PATCH 165/174] du: add srs config validator for du srs mng Signed-off-by: Carlo Galiotto --- .../du_srs_resource_manager.cpp | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index 7e74c8abba..ed5fc332c3 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -68,10 +68,56 @@ static bool is_partually_ul_slot(unsigned offset, const tdd_ul_dl_config_common& NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; } +static bool srs_config_validator(const du_cell_config& cell_cfg) +{ + if (not cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value()) { + return false; + } + + if (cell_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.has_value()) { + return false; + } + + const auto& srs_cfg = cell_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.value(); + if (srs_cfg.srs_res_set_list.size() != 1) { + return false; + } + + if (not std::holds_alternative( + srs_cfg.srs_res_set_list.front().res_type)) { + return false; + } + + if (srs_cfg.srs_res_set_list.front().srs_res_id_list.size() != 1 or + srs_cfg.srs_res_set_list.front().srs_res_id_list.front() != static_cast(0U)) { + return false; + } + + if (srs_cfg.srs_res_list.size() != 1 or + srs_cfg.srs_res_list.front().id.ue_res_id != static_cast(0U)) { + return false; + } + + if (srs_cfg.srs_res_list.front().res_type != srs_resource_type::periodic) { + return false; + } + + if (not srs_cfg.srs_res_list.front().periodicity_and_offset.has_value()) { + return false; + } + + return true; +} + du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell_cfg_list_) : cells(cell_cfg_list_.begin(), cell_cfg_list_.end()) { for (auto& cell : cells) { + if (not cell.cell_cfg.srs_cfg.srs_period.has_value()) { + continue; + } + + srsran_assert(srs_config_validator(cell.cell_cfg), "The SRS configuration is not valid"); std::optional c_srs = compute_srs_bw_param(cell.cell_cfg.ul_cfg_common.init_ul_bwp.generic_params.crbs.length()).value(); srsran_assert(c_srs.has_value(), "SRS parameters didn't provide a valid C_SRS value"); From 42ad6ba7d07552de6750c52bef3ee0c3754cf6ae Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Wed, 4 Sep 2024 16:14:39 +0200 Subject: [PATCH 166/174] du: fix bad_access to optional Signed-off-by: Carlo Galiotto --- .../du_ran_resource_manager_impl.cpp | 9 ++++++++ .../du_srs_resource_manager.cpp | 22 ++++++++++++++++--- .../du_srs_resource_manager.h | 4 +--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp index f217e60866..d8effa6425 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp @@ -164,11 +164,19 @@ error_type du_ran_resource_manager_impl::allocate_cell_resources(du } ue_res.cell_group.pcg_cfg.pdsch_harq_codebook = pdsch_harq_ack_codebook::dynamic; + if (not srs_res_mng->alloc_resources(ue_res.cell_group)) { + // Deallocate dedicated Search Spaces. + ue_res.cell_group.cells[0].serv_cell_cfg.init_dl_bwp.pdcch_cfg->search_spaces.clear(); + return make_unexpected(fmt::format("Unable to allocate SRS resources for cell={}", cell_index)); + } + if (not pucch_res_mng.alloc_resources(ue_res.cell_group)) { // Deallocate previously allocated SRS + dedicated Search Spaces. + srs_res_mng->dealloc_resources(ue_res.cell_group); ue_res.cell_group.cells[0].serv_cell_cfg.init_dl_bwp.pdcch_cfg->search_spaces.clear(); return make_unexpected(fmt::format("Unable to allocate dedicated PUCCH resources for cell={}", cell_index)); } + } else { srsran_assert(not ue_res.cell_group.cells.contains(serv_cell_index), "Reallocation of SCell detected"); ue_res.cell_group.cells.emplace(serv_cell_index); @@ -190,6 +198,7 @@ void du_ran_resource_manager_impl::deallocate_cell_resources(du_ue_index_t ue_in ue_res.cell_group.cells[0].serv_cell_cfg.cell_index != INVALID_DU_CELL_INDEX, "Double deallocation of same UE cell resources detected"); pucch_res_mng.dealloc_resources(ue_res.cell_group); + srs_res_mng->dealloc_resources(ue_res.cell_group); ue_res.cell_group.cells[0].serv_cell_cfg.cell_index = INVALID_DU_CELL_INDEX; } else { // TODO: Remove of SCell params. diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index ed5fc332c3..6d03c9259a 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -171,9 +171,24 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) { - // Allocation of SR PUCCH offset. + // TODO: Adapt this to the case of UEs with multiple cells configs. + srsran_assert( + cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value(), + "UE UL config is empty"); + + // If periodic SRS is not enabled, don't allocate anything and exit with success. + if (not cells[0].cell_cfg.srs_cfg.srs_period.has_value() or not cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index] + .cell_cfg.ue_ded_serv_cell_cfg.ul_config.value() + .init_ul_bwp.srs_cfg.has_value()) { + return true; + } + + // The UE SRS configuration is taken from a base configuration, saved in the GNB. The details that are UE specific + // will be added later on in this function. cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( - cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].default_srs_cfg); + cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index] + .cell_cfg.ue_ded_serv_cell_cfg.ul_config.value() + .init_ul_bwp.srs_cfg.value()); srs_config& ue_srs_cfg = cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); auto& free_srs_list = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_res_offset_free_list; @@ -273,7 +288,8 @@ du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() void du_srs_policy_max_ul_th::dealloc_resources(cell_group_config& cell_grp_cfg) { - if (not cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()) { + if (not cells[0].cell_cfg.srs_cfg.srs_period.has_value() or + not cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()) { return; } diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h index 2200ab196f..5246b6cec2 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h @@ -51,8 +51,7 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager private: struct cell_context { - cell_context(const du_cell_config& cfg) : - cell_cfg(cfg), default_srs_cfg(cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.value()){}; + cell_context(const du_cell_config& cfg) : cell_cfg(cfg){}; using pair_res_id_offset = std::pair; @@ -84,7 +83,6 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager using pair_cnt_max = std::pair; const du_cell_config& cell_cfg; - const srs_config default_srs_cfg; srs_cell_common srs_common_params; // List of all SRS resources available to the cell; these resources can be allocated over to different UEs over // different offsets. From eafcd15e76fb134cf99394c40f6a44e4599e0e0c Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 5 Sep 2024 16:05:12 +0200 Subject: [PATCH 167/174] asn1: fix srs config conversion Signed-off-by: Carlo Galiotto --- .../du_high/du_manager/converters/asn1_rrc_config_helpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp b/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp index e3de1c11da..6af1adc75d 100644 --- a/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp +++ b/lib/du/du_high/du_manager/converters/asn1_rrc_config_helpers.cpp @@ -2419,8 +2419,8 @@ asn1::rrc_nr::srs_res_s srsran::srs_du::make_asn1_rrc_srs_res(const srs_config:: } break; case srs_resource_type::periodic: { srsran_assert(cfg.periodicity_and_offset.has_value(), "Periodic resource must have periodicity and offset"); - auto& p_res = res.res_type.set_semi_persistent(); - make_asn1_rrc_srs_config_perioidicity_and_offset(p_res.periodicity_and_offset_sp, + auto& p_res = res.res_type.set_periodic(); + make_asn1_rrc_srs_config_perioidicity_and_offset(p_res.periodicity_and_offset_p, cfg.periodicity_and_offset.value()); } break; default: From e2d31e8805386a6c7e50e754dd008128f391218b Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 5 Sep 2024 16:33:13 +0200 Subject: [PATCH 168/174] du: add option to make SRS periodic vs aperiodic Signed-off-by: Carlo Galiotto --- .../config/cell_config_builder_params.h | 2 ++ .../du_srs_resource_manager.cpp | 5 +-- .../config/serving_cell_config_factory.cpp | 18 +++++++--- .../pucch_resource_generator_test.cpp | 35 +++++++++---------- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/include/srsran/scheduler/config/cell_config_builder_params.h b/include/srsran/scheduler/config/cell_config_builder_params.h index b4d4c30b16..82d4db1651 100644 --- a/include/srsran/scheduler/config/cell_config_builder_params.h +++ b/include/srsran/scheduler/config/cell_config_builder_params.h @@ -48,6 +48,8 @@ struct cell_config_builder_params { std::optional k_ssb; /// Whether to enable CSI-RS in the cell. bool csi_rs_enabled = true; + /// Defines whether the default SRS configuration has periodic vs aperiodic SRS. + bool srs_periodic_enabled = false; /// Number of DL ports for the cell. unsigned nof_dl_ports = 1; /// \brief Minimum k1 value used in the generation of the UE "dl-DataToUl-Ack", as per TS38.213, 9.1.2.1. diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index 6d03c9259a..745c149832 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -127,6 +127,7 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell srsran_assert(freq_shift.has_value(), "SRS parameters didn't provide a valid freq_shift value"); cell.srs_common_params.freq_shift = freq_shift.value(); + // TODO: evaluate whether we need to consider the case of multiple cells. cell.cell_srs_res_list = generate_cell_srs_list(cell.cell_cfg); const unsigned srs_period_slots = static_cast(cell.cell_cfg.srs_cfg.srs_period.value()); @@ -161,10 +162,10 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell continue; } } - cell.srs_res_offset_free_list.push_back({res.cell_res_id, offset}); + cell.srs_res_offset_free_list.emplace_back(res.cell_res_id, offset); ++offset_res_cnt; } - cell.slot_resource_cnt.push_back({0U, offset_res_cnt}); + cell.slot_resource_cnt.emplace_back(0U, offset_res_cnt); } } } diff --git a/lib/scheduler/config/serving_cell_config_factory.cpp b/lib/scheduler/config/serving_cell_config_factory.cpp index 319c47df98..d68a5d334b 100644 --- a/lib/scheduler/config/serving_cell_config_factory.cpp +++ b/lib/scheduler/config/serving_cell_config_factory.cpp @@ -497,16 +497,26 @@ srs_config srsran::config_helpers::make_default_srs_config(const cell_config_bui res.freq_hop.b_srs = 0; res.freq_hop.b_hop = 0; res.grp_or_seq_hop = srs_group_or_sequence_hopping::neither; - res.res_type = srs_resource_type::aperiodic; - res.sequence_id = params.pci; + if (params.srs_periodic_enabled) { + res.res_type = srs_resource_type::periodic; + res.periodicity_and_offset.emplace( + srs_config::srs_periodicity_and_offset{.period = srs_periodicity::sl40, .offset = 0}); + } else { + res.res_type = srs_resource_type::aperiodic; + } + res.sequence_id = params.pci; cfg.srs_res_set_list.emplace_back(); // TODO: Verify correctness of the config based on what we support. srs_config::srs_resource_set& res_set = cfg.srs_res_set_list.back(); res_set.id = static_cast(0); res_set.srs_res_id_list.emplace_back(static_cast(0)); - res_set.res_type = - srs_config::srs_resource_set::aperiodic_resource_type{.aperiodic_srs_res_trigger = 1, .slot_offset = 7}; + if (params.srs_periodic_enabled) { + res_set.res_type = srs_config::srs_resource_set::periodic_resource_type{}; + } else { + res_set.res_type = + srs_config::srs_resource_set::aperiodic_resource_type{.aperiodic_srs_res_trigger = 1, .slot_offset = 7}; + } res_set.srs_res_set_usage = srs_config::srs_resource_set::usage::codebook; res_set.p0 = -84; res_set.pathloss_ref_rs = static_cast(0); diff --git a/tests/unittests/du_manager/pucch_resource_generator_test.cpp b/tests/unittests/du_manager/pucch_resource_generator_test.cpp index cac097b199..4d14d46b93 100644 --- a/tests/unittests/du_manager/pucch_resource_generator_test.cpp +++ b/tests/unittests/du_manager/pucch_resource_generator_test.cpp @@ -678,7 +678,7 @@ class test_ue_pucch_config_builder : public ::testing::TestWithParam( csi_cfg.csi_report_cfg_list.front().report_cfg_type) and @@ -919,9 +919,9 @@ TEST_P(test_ue_pucch_config_builder, test_validator_too_many_resources) nof_f1_res, nof_f2_res, f1_params, f2_params, bwp_size, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP); } - const unsigned harq_idx_cfg = test_rgen::uniform_int(0, nof_harq_cfg_per_ue - 1); - const unsigned sr_idx_cfg = test_rgen::uniform_int(0, nof_sr_res_per_cell - 1); - const unsigned csi_idx_cfg = test_rgen::uniform_int(0, nof_csi_res_per_cell - 1); + const auto harq_idx_cfg = test_rgen::uniform_int(0, nof_harq_cfg_per_ue - 1); + const auto sr_idx_cfg = test_rgen::uniform_int(0, nof_sr_res_per_cell - 1); + const auto csi_idx_cfg = test_rgen::uniform_int(0, nof_csi_res_per_cell - 1); // Update pucch_cfg with the UE list of resources (with at max 8 HARQ F1, 8 HARQ F2, 4 SR). ue_pucch_config_builder(serv_cell_cfg, @@ -938,22 +938,21 @@ TEST_P(test_ue_pucch_config_builder, test_validator_too_many_resources) ASSERT_TRUE(verify_nof_res_and_idx(harq_idx_cfg, sr_idx_cfg, csi_idx_cfg)); } -INSTANTIATE_TEST_SUITE_P( - ue_pucch_config_builder, - test_ue_pucch_config_builder, - // clang-format off +INSTANTIATE_TEST_SUITE_P(ue_pucch_config_builder, + test_ue_pucch_config_builder, + // clang-format off // nof: f0 | f1 | f2 | harq | sr | csi // nof: f0 | f1 | f2 | cfg | sr | csi ::testing::Values( -// pucch_cfg_builder_params{ 0, 3, 6, 1, 2, 1 }, -// pucch_cfg_builder_params{ 0, 7, 3, 1, 1, 1 }, -// pucch_cfg_builder_params{ 0, 8, 8, 1, 4, 1 }, -// pucch_cfg_builder_params{ 0, 1, 1, 1, 1, 1 }, -// pucch_cfg_builder_params{ 0, 7, 7, 1, 3, 1 }, -// pucch_cfg_builder_params{ 0, 8, 8, 4, 4, 4 }, -// pucch_cfg_builder_params{ 0, 5, 2, 10, 2, 7 }, -// pucch_cfg_builder_params{ 0, 2, 7, 3, 7, 3 }, -// pucch_cfg_builder_params{ 0, 6, 4, 5, 6, 2 }, + pucch_cfg_builder_params{ 0, 3, 6, 1, 2, 1 }, + pucch_cfg_builder_params{ 0, 7, 3, 1, 1, 1 }, + pucch_cfg_builder_params{ 0, 8, 8, 1, 4, 1 }, + pucch_cfg_builder_params{ 0, 1, 1, 1, 1, 1 }, + pucch_cfg_builder_params{ 0, 7, 7, 1, 3, 1 }, + pucch_cfg_builder_params{ 0, 8, 8, 4, 4, 4 }, + pucch_cfg_builder_params{ 0, 5, 2, 10, 2, 7 }, + pucch_cfg_builder_params{ 0, 2, 7, 3, 7, 3 }, + pucch_cfg_builder_params{ 0, 6, 4, 5, 6, 2 }, pucch_cfg_builder_params{ 6, 0, 6, 1, 8, 8 }, pucch_cfg_builder_params{ 5, 0, 3, 1, 1, 1 }, pucch_cfg_builder_params{ 6, 0, 6, 1, 4, 1 }, @@ -969,5 +968,5 @@ INSTANTIATE_TEST_SUITE_P( pucch_cfg_builder_params{ 6, 0, 4, 5, 6, 2 }, pucch_cfg_builder_params{ 6, 0, 6, 3, 6, 0 } ) - // clang-format on + // clang-format on ); From 8f48456a5e8b50e20cc559fad985fa71a7c1ba25 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 12 Sep 2024 11:49:21 +0200 Subject: [PATCH 169/174] du: add unittets for du srs res manager Signed-off-by: Carlo Galiotto --- include/srsran/du/du_cell_config.h | 2 +- .../config/cell_config_builder_params.h | 2 - .../du_srs_resource_manager.cpp | 149 ++++---- .../du_srs_resource_manager.h | 13 +- .../config/serving_cell_config_factory.cpp | 18 +- .../du_ran_resource_manager_test.cpp | 319 ++++++++++++++++++ 6 files changed, 421 insertions(+), 82 deletions(-) diff --git a/include/srsran/du/du_cell_config.h b/include/srsran/du/du_cell_config.h index 64b41c11fc..14164550ec 100644 --- a/include/srsran/du/du_cell_config.h +++ b/include/srsran/du/du_cell_config.h @@ -113,7 +113,7 @@ struct srs_builder_params { /// \c Transmission comb number , as per TS 38.211, Section 6.4.1.4.2, or TS 38.331, "SRS-Resource". tx_comb_size tx_comb = tx_comb_size::n4; /// Defines the number of symbols per SRS resource. - srs_nof_symbols nof_symbols = n1; + srs_nof_symbols nof_symbols = srs_nof_symbols::n1; /// Defines the CS reuse factor for the SRS resources. /// \remark With 2 or 4 antenna ports, different cyclic shifts are used by the different antennas. This parameter /// defines how many UEs can be multiplexed in the same symbols and RBs by exploiting different cyclic shifts. diff --git a/include/srsran/scheduler/config/cell_config_builder_params.h b/include/srsran/scheduler/config/cell_config_builder_params.h index 82d4db1651..b4d4c30b16 100644 --- a/include/srsran/scheduler/config/cell_config_builder_params.h +++ b/include/srsran/scheduler/config/cell_config_builder_params.h @@ -48,8 +48,6 @@ struct cell_config_builder_params { std::optional k_ssb; /// Whether to enable CSI-RS in the cell. bool csi_rs_enabled = true; - /// Defines whether the default SRS configuration has periodic vs aperiodic SRS. - bool srs_periodic_enabled = false; /// Number of DL ports for the cell. unsigned nof_dl_ports = 1; /// \brief Minimum k1 value used in the generation of the UE "dl-DataToUl-Ack", as per TS38.213, 9.1.2.1. diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index 745c149832..6e4b3df663 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -15,30 +15,42 @@ using namespace srsran; using namespace srs_du; +// Helper that computes the SRS bandwidth parameter \f$C_{SRS}\f$ based on the number of UL RBs. static std::optional compute_srs_bw_param(unsigned nof_ul_rbs) { - // Iterate over Table 6.4.1.4.3-1, TS 38.211, and find the first \f$C_{SRS}\f$ value that provides the - // greatest \f$m_{SRS,0}\f$ such that it is less than or equal to number of UL RBs. + // Iterate over Table 6.4.1.4.3-1, TS 38.211, and find the minimum \f$C_{SRS}\f$ value that maximizes \f$m_{SRS,0}\f$ + // under the constraint \f$m_{SRS,0}\f$ <= UL RBs. // As per Table 6.4.1.4.3-1, TS 38.211, the maximum value of \f$C_{SRS}\f$ is 63. constexpr unsigned max_non_valid_c_srs = 64; - constexpr uint8_t b_srs_0 = 0; - for (uint8_t c_srs = 0; c_srs != max_non_valid_c_srs; c_srs++) { + // As per Table 6.4.1.4.3-1, TS 38.211, we do not consider frequency hopping. + constexpr uint8_t b_srs_0 = 0; + // Defines the pair of C_SRS and m_SRS values. + using pair_c_srs_m_srs = std::pair; + std::optional candidate_c_srs = std::nullopt; + for (uint8_t c_srs = 0; c_srs != max_non_valid_c_srs; ++c_srs) { auto srs_params = srs_configuration_get(c_srs, b_srs_0); - srsran_assert(srs_params.has_value(), "The SRS is not valid"); - if (c_srs == 0 and srs_params.value().m_srs > nof_ul_rbs) { - srsran_assertion_failure("C_SRS is not compatible with the number of UL RBs"); + if (not srs_params.has_value()) { + srsran_assertion_failure("C_SRS is not compatible with the current BW configuration"); return std::nullopt; } - if (srs_params.value().m_srs == nof_ul_rbs) { - return c_srs; + + // If there is no candidate C_SRS value, we set the first valid C_SRS value as the candidate. + if (not candidate_c_srs.has_value()) { + candidate_c_srs = pair_c_srs_m_srs{c_srs, srs_params.value().m_srs}; + } + // NOTE: the condition srs_params.value().m_srs > candidate_c_srs->second is used to find the minimum C_SRS value + // that maximizes m_SRS. + else if (srs_params.value().m_srs <= nof_ul_rbs and srs_params.value().m_srs > candidate_c_srs->second) { + candidate_c_srs = pair_c_srs_m_srs{c_srs, srs_params.value().m_srs}; } + // If we reach this point, no need to keep looking for a valid C_SRS value. if (srs_params.value().m_srs > nof_ul_rbs) { - return c_srs - 1; + break; } } - return max_non_valid_c_srs - 1; + return candidate_c_srs.value().first; } // Helper that returns the frequency shift value for the SRS; the value is computed in such a way that the SRS resources @@ -62,53 +74,48 @@ static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) static bool is_partually_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) { - const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0 and - srsran::get_active_tdd_dl_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != - NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + const unsigned nof_symbols = srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); + return nof_symbols != 0 and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; } -static bool srs_config_validator(const du_cell_config& cell_cfg) +// Helper that updates the starting SRS config with user-defined parameters. +static srs_config build_default_srs_cfg(const du_cell_config& default_cell_cfg) { - if (not cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value()) { - return false; - } - - if (cell_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.has_value()) { - return false; - } + srsran_assert(default_cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value() and + default_cell_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.has_value(), + "DU cell config is not valid"); - const auto& srs_cfg = cell_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.value(); - if (srs_cfg.srs_res_set_list.size() != 1) { - return false; + // If the DU is not configured for periodic SRS, we don't need to update the SRS configuration. + if (not default_cell_cfg.srs_cfg.srs_period.has_value()) { + return default_cell_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.value(); } - if (not std::holds_alternative( - srs_cfg.srs_res_set_list.front().res_type)) { - return false; - } - - if (srs_cfg.srs_res_set_list.front().srs_res_id_list.size() != 1 or - srs_cfg.srs_res_set_list.front().srs_res_id_list.front() != static_cast(0U)) { - return false; - } + auto srs_cfg = default_cell_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.value(); - if (srs_cfg.srs_res_list.size() != 1 or - srs_cfg.srs_res_list.front().id.ue_res_id != static_cast(0U)) { - return false; - } + srsran_assert(srs_cfg.srs_res_list.size() == 1 and srs_cfg.srs_res_set_list.size() == 1, + "The SRS resource list and the SRS resource set list are expected to have a single element"); - if (srs_cfg.srs_res_list.front().res_type != srs_resource_type::periodic) { - return false; - } + srs_config::srs_resource& res = srs_cfg.srs_res_list.back(); + res.res_type = srs_resource_type::periodic; + // Set offset to 0. The offset will be updated later on, when the UE is allocated the SRS resources. + res.periodicity_and_offset.emplace( + srs_config::srs_periodicity_and_offset{.period = default_cell_cfg.srs_cfg.srs_period.value(), .offset = 0}); + // Set the SRS resource ID to 0, as there is only 1 SRS resource per UE. + res.id.ue_res_id = static_cast(0U); - if (not srs_cfg.srs_res_list.front().periodicity_and_offset.has_value()) { - return false; - } + srs_config::srs_resource_set& res_set = srs_cfg.srs_res_set_list.back(); + res_set.res_type.emplace( + srs_config::srs_resource_set::periodic_resource_type{}); + // Set the SRS resource set ID to 0, as there is only 1 SRS resource set per UE. + res_set.id = static_cast(0U); - return true; + return srs_cfg; } +du_srs_policy_max_ul_th::cell_context::cell_context(const du_cell_config& cfg) : + cell_cfg(cfg), default_srs_cfg(build_default_srs_cfg(cfg)){}; + du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell_cfg_list_) : cells(cell_cfg_list_.begin(), cell_cfg_list_.end()) { @@ -117,7 +124,6 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell continue; } - srsran_assert(srs_config_validator(cell.cell_cfg), "The SRS configuration is not valid"); std::optional c_srs = compute_srs_bw_param(cell.cell_cfg.ul_cfg_common.init_ul_bwp.generic_params.crbs.length()).value(); srsran_assert(c_srs.has_value(), "SRS parameters didn't provide a valid C_SRS value"); @@ -130,19 +136,30 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell // TODO: evaluate whether we need to consider the case of multiple cells. cell.cell_srs_res_list = generate_cell_srs_list(cell.cell_cfg); - const unsigned srs_period_slots = static_cast(cell.cell_cfg.srs_cfg.srs_period.value()); + const auto srs_period_slots = static_cast(cell.cell_cfg.srs_cfg.srs_period.value()); cell.slot_resource_cnt.reserve(srs_period_slots); + cell.srs_res_offset_free_list.reserve(du_srs_policy_max_ul_th::cell_context::max_nof_srs_res); for (unsigned offset = 0; offset != srs_period_slots; ++offset) { + // We don't generate more than the maximum number of SRS resources per cell. + if (cell.srs_res_offset_free_list.size() >= du_srs_policy_max_ul_th::cell_context::max_nof_srs_res) { + break; + } + unsigned offset_res_cnt = 0U; + // Verify whether the offset maps to a partially- or fully-UL slot. + if (cell_cfg_list_[0].tdd_ul_dl_cfg_common.has_value() and + not is_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { + cell.slot_resource_cnt.emplace_back(0U, offset_res_cnt); + continue; + } + for (auto& res : cell.cell_srs_res_list) { - // Handle TDD and FDD configurations separately, as we treat partially-UL slots differently from fully-UL slots. + // Handle TDD and FDD configurations separately, as we treat partially-UL slots differently from + // fully-UL slots. if (cell_cfg_list_[0].tdd_ul_dl_cfg_common.has_value()) { - // Verify whether the offset maps to a partially- or fully-UL slot. - if (not is_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { - continue; - } - // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the slot. + // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the + // slot. if (is_partually_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { // TODO: Fix check for pattern 2. if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - @@ -184,12 +201,10 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) return true; } - // The UE SRS configuration is taken from a base configuration, saved in the GNB. The details that are UE specific - // will be added later on in this function. + // The UE SRS configuration is taken from a base configuration, saved in the GNB. The details that are + // UE specific will be added later on in this function. cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( - cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index] - .cell_cfg.ue_ded_serv_cell_cfg.ul_config.value() - .init_ul_bwp.srs_cfg.value()); + cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].default_srs_cfg); srs_config& ue_srs_cfg = cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); auto& free_srs_list = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_res_offset_free_list; @@ -220,7 +235,9 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) only_ue_srs_res.id.cell_res_id = du_res.cell_res_id; only_ue_srs_res.id.ue_res_id = static_cast(0U); only_ue_srs_res.periodicity_and_offset.value().offset = srs_offset; + only_ue_srs_res.tx_comb.size = cells[0].cell_cfg.srs_cfg.tx_comb; only_ue_srs_res.tx_comb.tx_comb_offset = du_res.tx_comb_offset.to_uint(); + only_ue_srs_res.tx_comb.tx_comb_cyclic_shift = du_res.cs; only_ue_srs_res.freq_domain_pos = du_res.freq_dom_position; only_ue_srs_res.res_mapping.start_pos = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_res.symbols.start() - 1; only_ue_srs_res.res_mapping.nof_symb = static_cast(du_res.symbols.length()); @@ -228,6 +245,10 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) // Update the SRS configuration with the parameters that are common to the cell. only_ue_srs_res.freq_hop.c_srs = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.c_srs; + // We assume that the frequency hopping is disabled and that the SRS occupies all possible RBs within the BWP. Refer + // to Section 6.4.1.4.3, TS 38.211. + only_ue_srs_res.freq_hop.b_srs = 0U; + only_ue_srs_res.freq_hop.b_hop = 0U; only_ue_srs_res.freq_domain_shift = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.freq_shift; @@ -249,7 +270,8 @@ du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() // The weights assigned here can be set to any value, as long as: // - symbol_weight_base is greater than 0; // - reuse_slot_discount less than symbol_weight_base; - // - max_weight is > symbol_weight_base * (srs_builder_params::max_nof_symbols / srs_builder_params::nof_symbols). + // - max_weight is > symbol_weight_base * (srs_builder_params::max_nof_symbols / + // srs_builder_params::nof_symbols). static constexpr unsigned max_weight = 100U; static constexpr unsigned symbol_weight_base = 10U; @@ -270,8 +292,9 @@ du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() const unsigned symb_weight = (NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res_cfg_it->symbols.start()) * symbol_weight_base; - // We consider a discount if the offset is already used but not full; this way, we give an incentive to the SRS - // resources not to be allocated on a new slot, to avoid taking PUSCH symbols on a new slot. + // We consider a discount if the offset is already used but not full; this way, we give an incentive + // to the SRS resources not to be allocated on a new slot, to avoid taking PUSCH symbols on a new + // slot. const unsigned reuse_slot_discount = offset_used_not_full(srs_res.second) ? symbol_weight_base / 2U : 0U; return symb_weight - reuse_slot_discount; @@ -299,7 +322,7 @@ void du_srs_policy_max_ul_th::dealloc_resources(cell_group_config& cell_grp_cfg) for (const auto& srs_res : ue_srs_cfg.srs_res_list) { const unsigned offset_to_deallocate = srs_res.periodicity_and_offset.value().offset; - free_srs_list.push_back({srs_res.id.cell_res_id, offset_to_deallocate}); + free_srs_list.emplace_back(srs_res.id.cell_res_id, offset_to_deallocate); // Update the used_not_full slot vector. srsran_assert(cells[0].slot_resource_cnt[offset_to_deallocate].first != 0, "The offset is expected to be non-zero"); diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h index 5246b6cec2..65bc16519c 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h @@ -13,7 +13,7 @@ #include "srs_resource_generator.h" #include "srsran/adt/optional.h" #include "srsran/du/du_cell_config.h" -#include "srsran/ran/srs/srs_configuration.h" +#include "srsran/ran/srs/srs_bandwidth_configuration.h" namespace srsran { namespace srs_du { @@ -51,7 +51,7 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager private: struct cell_context { - cell_context(const du_cell_config& cfg) : cell_cfg(cfg){}; + cell_context(const du_cell_config& cfg); using pair_res_id_offset = std::pair; @@ -82,8 +82,15 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager using pair_cnt_max = std::pair; + // Maximum number of SRS resources that can be generated in a cell. + // [Implementation-defined] We assume each UE has one and only one resource. + static const unsigned max_nof_srs_res = MAX_NOF_DU_UES; + // We need to save an object with the cell configuration parameters (not a reference), as this config is a modified + // version of the default cell config. const du_cell_config& cell_cfg; - srs_cell_common srs_common_params; + // Default SRS configuration for the cell. + const srs_config default_srs_cfg; + srs_cell_common srs_common_params; // List of all SRS resources available to the cell; these resources can be allocated over to different UEs over // different offsets. std::vector cell_srs_res_list; diff --git a/lib/scheduler/config/serving_cell_config_factory.cpp b/lib/scheduler/config/serving_cell_config_factory.cpp index d68a5d334b..a53f5dd348 100644 --- a/lib/scheduler/config/serving_cell_config_factory.cpp +++ b/lib/scheduler/config/serving_cell_config_factory.cpp @@ -497,13 +497,8 @@ srs_config srsran::config_helpers::make_default_srs_config(const cell_config_bui res.freq_hop.b_srs = 0; res.freq_hop.b_hop = 0; res.grp_or_seq_hop = srs_group_or_sequence_hopping::neither; - if (params.srs_periodic_enabled) { - res.res_type = srs_resource_type::periodic; - res.periodicity_and_offset.emplace( - srs_config::srs_periodicity_and_offset{.period = srs_periodicity::sl40, .offset = 0}); - } else { - res.res_type = srs_resource_type::aperiodic; - } + res.res_type = srs_resource_type::aperiodic; + res.sequence_id = params.pci; cfg.srs_res_set_list.emplace_back(); @@ -511,12 +506,9 @@ srs_config srsran::config_helpers::make_default_srs_config(const cell_config_bui srs_config::srs_resource_set& res_set = cfg.srs_res_set_list.back(); res_set.id = static_cast(0); res_set.srs_res_id_list.emplace_back(static_cast(0)); - if (params.srs_periodic_enabled) { - res_set.res_type = srs_config::srs_resource_set::periodic_resource_type{}; - } else { - res_set.res_type = - srs_config::srs_resource_set::aperiodic_resource_type{.aperiodic_srs_res_trigger = 1, .slot_offset = 7}; - } + res_set.res_type = + srs_config::srs_resource_set::aperiodic_resource_type{.aperiodic_srs_res_trigger = 1, .slot_offset = 7}; + res_set.srs_res_set_usage = srs_config::srs_resource_set::usage::codebook; res_set.p0 = -84; res_set.pathloss_ref_rs = static_cast(0); diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index b1e8050b21..648a7501d8 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -785,3 +785,322 @@ INSTANTIATE_TEST_SUITE_P( ) // clang-format on ); + +struct srs_params { + // If set, it's a TDD cell and the parameters indicates the number of UL symbols in the flexible slot. + std::optional nof_ul_symbols; +}; + +static cell_config_builder_params make_cell_cfg_params(const srs_params& params) +{ + const bool is_tdd = params.nof_ul_symbols.has_value(); + cell_config_builder_params cell_params = {.dl_f_ref_arfcn = not is_tdd ? 365000U : 520002U}; + if (is_tdd) { + auto& tdd_cfg = cell_params.tdd_ul_dl_cfg_common.emplace(); + tdd_cfg.pattern1.dl_ul_tx_period_nof_slots = 10; + tdd_cfg.pattern1.nof_dl_slots = 7; + tdd_cfg.pattern1.nof_dl_symbols = 2; + tdd_cfg.pattern1.nof_ul_slots = 2; + tdd_cfg.pattern1.nof_ul_symbols = params.nof_ul_symbols.value(); + } + + return cell_params; +} + +static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& params) +{ + du_cell_config du_cfg = config_helpers::make_default_du_cell_config(params); + auto& srs_cfg = du_cfg.srs_cfg; + + auto& tdd_cfg = du_cfg.tdd_ul_dl_cfg_common.emplace(); + tdd_cfg.pattern1.dl_ul_tx_period_nof_slots = 10; + tdd_cfg.pattern1.nof_dl_slots = 7; + tdd_cfg.pattern1.nof_dl_symbols = 8; + tdd_cfg.pattern1.nof_ul_slots = 2; + tdd_cfg.pattern1.nof_ul_symbols = 4; + + // Generates a random SRS configuration. + srs_cfg.tx_comb = test_rgen::bernoulli(0.5) ? tx_comb_size::n2 : tx_comb_size::n4; + srs_cfg.max_nof_symbols = test_rgen::uniform_int(1U, 6U); + // The number of SRS symbols cannot exceed the number of + std::array nof_symb_values = {srs_nof_symbols::n1, srs_nof_symbols::n2, srs_nof_symbols::n4}; + srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; + while (srs_cfg.nof_symbols > srs_cfg.max_nof_symbols) { + srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; + } + // The TX comb cyclic shift value depends on the TX comb size. + if (srs_cfg.tx_comb == srsran::tx_comb_size::n2) { + std::array srs_cyclic_shift_values = { + nof_cyclic_shifts::no_cyclic_shift, nof_cyclic_shifts::two, nof_cyclic_shifts::four}; + srs_cfg.cyclic_shift_reuse_factor = + srs_cyclic_shift_values[test_rgen::uniform_int(0, srs_cyclic_shift_values.size() - 1)]; + } else { + std::array srs_cyclic_shift_values = {nof_cyclic_shifts::no_cyclic_shift, + nof_cyclic_shifts::two, + nof_cyclic_shifts::three, + nof_cyclic_shifts::four, + nof_cyclic_shifts::six, + nof_cyclic_shifts::twelve}; + srs_cfg.cyclic_shift_reuse_factor = + srs_cyclic_shift_values[test_rgen::uniform_int(0, srs_cyclic_shift_values.size() - 1)]; + } + // [Implementation-defined] These are the values in the gNB, \ref sequence_id_reuse_factor. + std::array srs_seq_id_values = {1, 2, 3, 5, 6, 10, 15, 30}; + srs_cfg.sequence_id_reuse_factor = + srs_seq_id_values[test_rgen::uniform_int(0, srs_seq_id_values.size() - 1)]; + + if (du_cfg.tdd_ul_dl_cfg_common.has_value()) { + std::array period_values = {srs_periodicity::sl10, + srs_periodicity::sl20, + srs_periodicity::sl40, + srs_periodicity::sl80, + srs_periodicity::sl160}; + srs_cfg.srs_period.emplace(period_values[test_rgen::uniform_int(0, period_values.size() - 1)]); + } else { + std::array period_values = {srs_periodicity::sl1, + srs_periodicity::sl2, + srs_periodicity::sl4, + srs_periodicity::sl5, + srs_periodicity::sl8, + srs_periodicity::sl10, + srs_periodicity::sl16, + srs_periodicity::sl20, + srs_periodicity::sl32, + srs_periodicity::sl40}; + srs_cfg.srs_period.emplace(period_values[test_rgen::uniform_int(0, period_values.size() - 1)]); + } + + return du_cfg; +} + +class du_srs_resource_manager_tester : public ::testing::TestWithParam +{ +protected: + explicit du_srs_resource_manager_tester(cell_config_builder_params params_ = make_cell_cfg_params(GetParam())) : + params(params_), + cell_cfg_list({make_srs_du_cell_config(params_)}), + srs_params(cell_cfg_list[0].srs_cfg), + du_srs_res_mng(cell_cfg_list) + { + } + + std::optional add_ue(du_ue_index_t ue_idx) + { + if (ue_idx >= MAX_NOF_DU_UES) { + return std::nullopt; + } + + cell_group_config cell_grp_cfg; + std::unique_ptr cell_grp_cfg_ptr = std::make_unique(); + cell_grp_cfg.cells.insert( + serv_cell_index_t::SERVING_CELL_PCELL_IDX, + cell_config_dedicated{serv_cell_index_t::SERVING_CELL_PCELL_IDX, + config_helpers::create_default_initial_ue_serving_cell_config(params)}); + ues.insert(ue_idx, cell_grp_cfg); + auto& ue = ues[ue_idx]; + + if (du_srs_res_mng.alloc_resources(ue)) { + return ue; + } + // If the allocation was not possible, remove the UE. + ues.erase(ue_idx); + return std::nullopt; + } + + struct srs_res_params { + unsigned offset; + unsigned tx_comb_offset; + ofdm_symbol_range symbols; + unsigned sequence_id; + unsigned cs; + + // Constructor for the srs_res_params struct given srs_resource. + explicit srs_res_params(const srs_config::srs_resource& srs_res) : + offset(srs_res.periodicity_and_offset->offset), + tx_comb_offset(srs_res.tx_comb.tx_comb_offset), + symbols(ofdm_symbol_range{NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res.res_mapping.start_pos - 1, + NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res.res_mapping.start_pos - 1 + + srs_res.res_mapping.nof_symb}), + sequence_id(srs_res.sequence_id), + cs(srs_res.tx_comb.tx_comb_cyclic_shift) + { + } + + bool collides(const srs_res_params& rhs) const + { + return offset == rhs.offset and tx_comb_offset == rhs.tx_comb_offset and symbols.overlaps(rhs.symbols) and + sequence_id == rhs.sequence_id and cs == rhs.cs; + } + + bool operator==(const srs_res_params& rhs) const + { + return offset == rhs.offset and tx_comb_offset == rhs.tx_comb_offset and symbols == rhs.symbols and + sequence_id == rhs.sequence_id and cs == rhs.cs; + } + + bool operator!=(const srs_res_params& rhs) const { return not operator==(rhs); } + }; + + unsigned compute_c_srs() const + { + // In this test, we only consider the case where B_SRS is 0. + const uint8_t b_srs = 0U; + unsigned candidate_c_srs = 0U; + unsigned candidate_m_srs = 0U; + // Spans over Table 6.4.1.4.3-1 in TS 38.211 and find the smallest C_SRS that maximizes m_srs_0 under the + // constraint of m_SRS <= nof_BW_RBs. + for (unsigned c_srs_it = 0; c_srs_it != 64; ++c_srs_it) { + std::optional srs_cfg = srs_configuration_get(c_srs_it, b_srs); + srsran_assert(srs_cfg.has_value(), "C_SRS is required for this unittest"); + if (srs_cfg.value().m_srs <= cell_cfg_list[0].ul_cfg_common.init_ul_bwp.generic_params.crbs.length() and + srs_cfg.value().m_srs > candidate_m_srs) { + candidate_m_srs = srs_cfg->m_srs; + candidate_c_srs = c_srs_it; + } + } + return candidate_c_srs; + } + + unsigned compute_freq_shift() const + { + unsigned c_srs = compute_c_srs(); + unsigned ul_bw_nof_rbs = cell_cfg_list[0].ul_cfg_common.init_ul_bwp.generic_params.crbs.length(); + const auto srs_cfg = srs_configuration_get(c_srs, 0U); + srsran_assert(srs_cfg.has_value(), "C_SRS is required for this unittest"); + return (ul_bw_nof_rbs - srs_cfg.value().m_srs) / 2U; + } + + cell_config_builder_params params; + std::vector cell_cfg_list; + // This is a reference to the first element of cell_cfg_list's SRS config. + const srs_builder_params& srs_params; + du_srs_policy_max_ul_th du_srs_res_mng; + slotted_array ues; +}; + +static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0; +} + +static bool is_partually_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + const unsigned nof_symbols = srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); + return nof_symbols != 0 and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; +} + +TEST_P(du_srs_resource_manager_tester, ue_are_assigned_orthogonal_srs_resources) +{ + du_ue_index_t next_ue_index = to_du_ue_index(0); + + // Keeps track of which SRS resources have been assigned to the UEs. + std::vector used_srs_resources; + // > Created UEs have unique SRS resources. + for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { + std::optional ue = add_ue(to_du_ue_index(i)); + if (not ue.has_value()) { + break; + } + + // Check if the SRS has been assigned to the UE. + const auto& srs_res_list = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list; + ASSERT_FALSE(srs_res_list.empty()); + // Check if the SRS resource collides (i.e., is not orthogonal) with any other SRS resource. + const auto& srs_res = srs_res_list[0]; + const srs_res_params res_params(srs_res); + ASSERT_FALSE(std::any_of(used_srs_resources.begin(), + used_srs_resources.end(), + [&res_params](const srs_res_params& res) { return res.collides(res_params); })); + + used_srs_resources.push_back(res_params); + next_ue_index = to_du_ue_index((unsigned)next_ue_index + 1); + } + + // Erase a random UE and attempt. + const du_ue_index_t ue_idx_to_rem = to_du_ue_index(test_rgen::uniform_int(0, ues.size() - 1)); + du_srs_res_mng.dealloc_resources(ues[ue_idx_to_rem]); + auto& ue_to_be_removed = ues[ue_idx_to_rem]; + // First, find the SRS resource of the ue to be removed and removed it from the vector of used resources. + srs_res_params srs_res_to_be_removed( + ue_to_be_removed.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list[0]); + auto res_to_remove_it = std::find(used_srs_resources.begin(), used_srs_resources.end(), srs_res_to_be_removed); + ASSERT_FALSE(res_to_remove_it == used_srs_resources.end()); + used_srs_resources.erase(res_to_remove_it); + ues.erase(ue_idx_to_rem); + + // Attempt a new allocation and verify it is successful. + next_ue_index = to_du_ue_index((unsigned)next_ue_index + 1); + std::optional ue = add_ue(ue_idx_to_rem); + ASSERT_TRUE(ue.has_value()); + + // Check if the SRS has been assigned to the UE. + const auto& srs_res_list = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list; + ASSERT_FALSE(srs_res_list.empty()); + // Check if the SRS resource collides (i.e., is not orthogonal) with any other SRS resource. + const auto& srs_res = srs_res_list[0]; + const srs_res_params res_params(srs_res); + ASSERT_FALSE(std::any_of(used_srs_resources.begin(), + used_srs_resources.end(), + [&res_params](const srs_res_params& res) { return res.collides(res_params); })); +} + +TEST_P(du_srs_resource_manager_tester, srs_resources_parameters_are_valid) +{ + // > Created UEs have unique SRS resources. + for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { + std::optional ue = add_ue(to_du_ue_index(i)); + if (not ue.has_value()) { + break; + } + + ASSERT_TRUE(ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); + const auto& ue_srs_config = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + // Verify first the SRS resource set list. + ASSERT_EQ(ue_srs_config.srs_res_set_list.size(), 1U); + ASSERT_EQ(ue_srs_config.srs_res_set_list[0].id, 0U); + ASSERT_TRUE(std::holds_alternative( + ue_srs_config.srs_res_set_list[0].res_type)); + ASSERT_EQ(ue_srs_config.srs_res_set_list[0].srs_res_id_list.size(), 1U); + ASSERT_EQ(ue_srs_config.srs_res_set_list[0].srs_res_id_list[0], 0U); + ASSERT_EQ(ue_srs_config.srs_res_list.size(), 1U); + const auto& srs_res = ue_srs_config.srs_res_list[0]; + ASSERT_EQ(srs_res.id.ue_res_id, static_cast(0U)); + ASSERT_TRUE(srs_res.periodicity_and_offset.has_value()); + ASSERT_EQ(srs_res.periodicity_and_offset->period, srs_params.srs_period.value()); + ASSERT_LT(srs_res.periodicity_and_offset->offset, static_cast(srs_res.periodicity_and_offset->period)); + if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value()) { + ASSERT_TRUE(is_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())); + } + ASSERT_LT(srs_res.tx_comb.tx_comb_offset, static_cast(srs_res.tx_comb.size)); + ASSERT_LT(srs_res.tx_comb.tx_comb_cyclic_shift, srs_res.tx_comb.size == tx_comb_size::n2 ? 8U : 12U); + + ASSERT_EQ(srs_res.freq_hop.c_srs, compute_c_srs()); + ASSERT_EQ(srs_res.freq_hop.b_srs, 0U); + ASSERT_EQ(srs_res.freq_hop.b_hop, 0U); + ASSERT_EQ(srs_res.freq_domain_shift, compute_freq_shift()); + ASSERT_EQ(srs_res.freq_domain_pos, 0U); + + // Verify the symbols, depending on whether it's FDD, or TDD. + ASSERT_EQ(srs_res.res_mapping.nof_symb, srs_params.nof_symbols); + if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value() and + is_partually_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { + ASSERT_LT(srs_res.res_mapping.start_pos, cell_cfg_list[0].tdd_ul_dl_cfg_common.value().pattern1.nof_ul_symbols); + } else { + ASSERT_LT(srs_res.res_mapping.start_pos, srs_params.max_nof_symbols.to_uint()); + } + } +} + +INSTANTIATE_TEST_SUITE_P(test_du_srs_res_mng_for_different_ul_symbols, + du_srs_resource_manager_tester, + ::testing::Values(srs_params{.nof_ul_symbols = std::nullopt}, + srs_params{.nof_ul_symbols = 0U}, + srs_params{.nof_ul_symbols = 1U}, + srs_params{.nof_ul_symbols = 2U}, + srs_params{.nof_ul_symbols = 3U}, + srs_params{.nof_ul_symbols = 4U}, + srs_params{.nof_ul_symbols = 5U}, + srs_params{.nof_ul_symbols = 6U}, + srs_params{.nof_ul_symbols = 7U})); From 38a96353bfe497fdad73485ac068dc7057e2541f Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 19 Sep 2024 18:19:24 +0200 Subject: [PATCH 170/174] du: fix missing antenna port param in srs resource Signed-off-by: Carlo Galiotto --- .../du_srs_resource_manager.cpp | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index 6e4b3df663..a7f13837ae 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -232,16 +232,20 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) auto& only_ue_srs_res = ue_srs_cfg.srs_res_list.front(); const unsigned srs_offset = srs_res_id_offset->second; // NOTE: given that there is only 1 SRS resource per UE, we can assume that the SRS resource ID is 0. - only_ue_srs_res.id.cell_res_id = du_res.cell_res_id; - only_ue_srs_res.id.ue_res_id = static_cast(0U); - only_ue_srs_res.periodicity_and_offset.value().offset = srs_offset; - only_ue_srs_res.tx_comb.size = cells[0].cell_cfg.srs_cfg.tx_comb; - only_ue_srs_res.tx_comb.tx_comb_offset = du_res.tx_comb_offset.to_uint(); - only_ue_srs_res.tx_comb.tx_comb_cyclic_shift = du_res.cs; - only_ue_srs_res.freq_domain_pos = du_res.freq_dom_position; - only_ue_srs_res.res_mapping.start_pos = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_res.symbols.start() - 1; - only_ue_srs_res.res_mapping.nof_symb = static_cast(du_res.symbols.length()); - only_ue_srs_res.sequence_id = du_res.sequence_id; + only_ue_srs_res.id.cell_res_id = du_res.cell_res_id; + only_ue_srs_res.id.ue_res_id = static_cast(0U); + srsran_assert(cells[0].cell_cfg.ul_carrier.nof_ant == 1 or cells[0].cell_cfg.ul_carrier.nof_ant == 2 or + cells[0].cell_cfg.ul_carrier.nof_ant == 4, + "The number of UL antenna ports is not valid"); + only_ue_srs_res.nof_ports = + static_cast(cells[0].cell_cfg.ul_carrier.nof_ant); + only_ue_srs_res.tx_comb.size = cells[0].cell_cfg.srs_cfg.tx_comb; + only_ue_srs_res.tx_comb.tx_comb_offset = du_res.tx_comb_offset.to_uint(); + only_ue_srs_res.tx_comb.tx_comb_cyclic_shift = du_res.cs; + only_ue_srs_res.freq_domain_pos = du_res.freq_dom_position; + only_ue_srs_res.res_mapping.start_pos = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_res.symbols.start() - 1; + only_ue_srs_res.res_mapping.nof_symb = static_cast(du_res.symbols.length()); + only_ue_srs_res.sequence_id = du_res.sequence_id; // Update the SRS configuration with the parameters that are common to the cell. only_ue_srs_res.freq_hop.c_srs = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.c_srs; From a11bb33cde211ed184480099d97e3940c4cf5a0b Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Wed, 25 Sep 2024 17:33:08 +0200 Subject: [PATCH 171/174] du: fix RAN resource deallocation + add unittest Signed-off-by: Carlo Galiotto --- .../du_pucch_resource_manager.cpp | 4 + .../du_ran_resource_manager_impl.cpp | 20 +- .../du_srs_resource_manager.cpp | 39 +- .../du_srs_resource_manager.h | 18 +- .../du_ran_resource_manager_test.cpp | 414 ++++++++++++++++-- 5 files changed, 450 insertions(+), 45 deletions(-) diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp index 56134f64bb..25fb1cec46 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp @@ -348,6 +348,10 @@ void du_pucch_resource_manager::dealloc_resources(cell_group_config& cell_grp_cf srsran_assert(cells[0].pucch_grants_per_slot_cnt[offset] != 0, "Index exceeds the size of the PUCCH grants vector"); --cells[0].pucch_grants_per_slot_cnt[offset]; } + + // Disable the PUCCH configuration in this UE. This makes sure the DU will exit this function immediately when it gets + // call again for the same UE (upon destructor's call). + disable_pucch_cfg(cell_grp_cfg); } std::vector>::const_iterator diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp index d8effa6425..74eda4f195 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp @@ -38,6 +38,21 @@ du_ue_ran_resource_updater_impl::update(du_cell_index_t pc /////////////////////////// +static void initialize_serv_cell_cfg(serving_cell_config& serv_cell_cfg) +{ + srsran_assert(serv_cell_cfg.ul_config.has_value() and + serv_cell_cfg.ul_config.value().init_ul_bwp.pucch_cfg.has_value() and + serv_cell_cfg.ul_config.value().init_ul_bwp.srs_cfg.has_value(), + "UL configuration in Serving cell config not configured"); + + serv_cell_cfg.ul_config->init_ul_bwp.pucch_cfg.reset(); + if (serv_cell_cfg.csi_meas_cfg.has_value()) { + serv_cell_cfg.csi_meas_cfg.value().csi_report_cfg_list.clear(); + } + + serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); +} + du_ran_resource_manager_impl::du_ran_resource_manager_impl(span cell_cfg_list_, const scheduler_expert_config& scheduler_cfg, const std::map& srb_config, @@ -64,7 +79,6 @@ du_ran_resource_manager_impl::create_ue_resource_configurator(du_ue_index_t ue_i // UE initialized PCell. // Note: In case of lack of RAN resource availability, the return will be error type. error_type err = allocate_cell_resources(ue_index, pcell_index, SERVING_CELL_PCELL_IDX); - return ue_ran_resource_configurator{std::make_unique(&mcg, *this, ue_index), err.has_value() ? std::string{} : err.error()}; } @@ -164,6 +178,10 @@ error_type du_ran_resource_manager_impl::allocate_cell_resources(du } ue_res.cell_group.pcg_cfg.pdsch_harq_codebook = pdsch_harq_ack_codebook::dynamic; + // Start with removing PUCCH and SRS configurations. This step simplifies the handling of the allocation failure + // path. + initialize_serv_cell_cfg(ue_res.cell_group.cells[0].serv_cell_cfg); + if (not srs_res_mng->alloc_resources(ue_res.cell_group)) { // Deallocate dedicated Search Spaces. ue_res.cell_group.cells[0].serv_cell_cfg.init_dl_bwp.pdcch_cfg->search_spaces.clear(); diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index a7f13837ae..c4c836c4a8 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -158,12 +158,17 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell // Handle TDD and FDD configurations separately, as we treat partially-UL slots differently from // fully-UL slots. if (cell_cfg_list_[0].tdd_ul_dl_cfg_common.has_value()) { + const auto& tdd_cfg = cell_cfg_list_[0].tdd_ul_dl_cfg_common.value(); // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the // slot. if (is_partually_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { - // TODO: Fix check for pattern 2. - if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - - cell_cfg_list_[0].tdd_ul_dl_cfg_common.value().pattern1.nof_ul_symbols) { + const unsigned slot_index = + offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + static constexpr unsigned max_srs_symbols = 6U; + const unsigned nof_ul_symbols_for_srs = + std::min(srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(), + max_srs_symbols); + if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - nof_ul_symbols_for_srs) { continue; } } @@ -191,13 +196,15 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) { // TODO: Adapt this to the case of UEs with multiple cells configs. srsran_assert( - cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value(), - "UE UL config is empty"); + cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value() and + not cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value(), + "UE UL config should be non-empty but with an empty SRS config"); + + cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( + cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].default_srs_cfg); // If periodic SRS is not enabled, don't allocate anything and exit with success. - if (not cells[0].cell_cfg.srs_cfg.srs_period.has_value() or not cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index] - .cell_cfg.ue_ded_serv_cell_cfg.ul_config.value() - .init_ul_bwp.srs_cfg.has_value()) { + if (not cells[0].cell_cfg.srs_cfg.srs_period.has_value()) { return true; } @@ -210,6 +217,8 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) // Verify where there are SRS resources to allocate a new UE. if (free_srs_list.empty()) { + // If the allocation failed, reset the SRS configuration. + cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); return false; } @@ -217,12 +226,16 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) auto srs_res_id_offset = cells[0].find_optimal_ue_srs_resource(); if (srs_res_id_offset == free_srs_list.end()) { + // If the allocation failed, reset the SRS configuration. + cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); return false; } const auto& du_res_it = cells[0].get_du_srs_res_cfg(srs_res_id_offset->first); if (du_res_it == cells[0].cell_srs_res_list.end()) { + // If the allocation failed, reset the SRS configuration. + cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); return false; } @@ -256,6 +269,9 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) only_ue_srs_res.freq_domain_shift = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.freq_shift; + only_ue_srs_res.periodicity_and_offset.emplace(srs_config::srs_periodicity_and_offset{ + .period = cells[0].cell_cfg.srs_cfg.srs_period.value(), .offset = static_cast(srs_offset)}); + // Update the SRS resource set with the SRS id. ue_srs_cfg.srs_res_set_list.front().srs_res_id_list.front() = only_ue_srs_res.id.ue_res_id; @@ -294,7 +310,8 @@ du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() // Give priority to the last symbols within a slot. This reduces the space used for the SRS in a slot. const unsigned symb_weight = - (NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res_cfg_it->symbols.start()) * symbol_weight_base; + symbol_weight_base * + ((NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res_cfg_it->symbols.start()) / srs_res_cfg_it->symbols.length()); // We consider a discount if the offset is already used but not full; this way, we give an incentive // to the SRS resources not to be allocated on a new slot, to avoid taking PUSCH symbols on a new @@ -332,4 +349,8 @@ void du_srs_policy_max_ul_th::dealloc_resources(cell_group_config& cell_grp_cfg) srsran_assert(cells[0].slot_resource_cnt[offset_to_deallocate].first != 0, "The offset is expected to be non-zero"); --cells[0].slot_resource_cnt[offset_to_deallocate].first; } + + // Reset the SRS configuration in this UE. This makes sure the DU will exit this function immediately when it gets + // call again for the same UE (upon destructor's call). + cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); } diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h index 65bc16519c..433bbddf9c 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h @@ -36,10 +36,10 @@ class du_srs_resource_manager virtual void dealloc_resources(cell_group_config& cell_grp_cfg) = 0; }; -/// This class implements the MAX UL throughput policy for the SRS allocation. The SRS resources are allocated to -/// minimize the number of slots that contains the SRS resources; furthermore, within a given slot, the SRS resources -/// are allocated to minimize the number of symbols that are used for SRS. The drawback of this policy is that it can -/// increase the inter slot SRS interference among different UEs. +/// This class implements the MAX UL throughput policy for the SRS allocation. The SRS resources are allocated with the +/// objective to minimize the number of slots that contains the SRS resources; furthermore, within a given slot, the SRS +/// resources are allocated to minimize the number of symbols that are used for SRS. The drawback of this policy is that +/// it can increase the inter slot SRS interference among different UEs. class du_srs_policy_max_ul_th : public du_srs_resource_manager { public: @@ -58,9 +58,11 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager // Returns the DU SRS resource with the given cell resource ID from the cell list of resources. std::vector::const_iterator get_du_srs_res_cfg(unsigned cell_res_id) { - return std::find_if(cell_srs_res_list.begin(), - cell_srs_res_list.end(), - [cell_res_id](const du_srs_resource& res) { return res.cell_res_id == cell_res_id; }); + if (cell_res_id >= cell_srs_res_list.size() or cell_srs_res_list[cell_res_id].cell_res_id != cell_res_id) { + srsran_assertion_failure("Cell resource ID out of range or invalid"); + return cell_srs_res_list.end(); + } + return cell_srs_res_list.cbegin() + cell_res_id; } // Returns the best SRS resource ID and offset for this UE, according to the policy defined in this class. @@ -85,8 +87,6 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager // Maximum number of SRS resources that can be generated in a cell. // [Implementation-defined] We assume each UE has one and only one resource. static const unsigned max_nof_srs_res = MAX_NOF_DU_UES; - // We need to save an object with the cell configuration parameters (not a reference), as this config is a modified - // version of the default cell config. const du_cell_config& cell_cfg; // Default SRS configuration for the cell. const srs_config default_srs_cfg; diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index 648a7501d8..25c7a8107c 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -12,6 +12,7 @@ #include "srsran/du/du_cell_config_helpers.h" #include "srsran/du/du_high/du_qos_config_helpers.h" #include "srsran/support/test_utils.h" +#include "fmt/ostream.h" #include using namespace srsran; @@ -786,14 +787,33 @@ INSTANTIATE_TEST_SUITE_P( // clang-format on ); +///////// Test DU RAN resource manager for SRS resources ///////// + +namespace { + struct srs_params { // If set, it's a TDD cell and the parameters indicates the number of UL symbols in the flexible slot. - std::optional nof_ul_symbols; + std::optional nof_ul_symbols_p1; + bool test_optimality = false; }; +std::ostream& operator<<(std::ostream& out, const srs_params& params) +{ + if (params.nof_ul_symbols_p1.has_value()) { + out << fmt::format("TDD_nof_ul_symbols_p1_{}_test_optimality_{}", + params.nof_ul_symbols_p1.value(), + params.test_optimality ? "true" : "false"); + } else { + out << fmt::format("FDD_test_optimality_{}", params.test_optimality ? "true" : "false"); + } + return out; +} + +} // namespace + static cell_config_builder_params make_cell_cfg_params(const srs_params& params) { - const bool is_tdd = params.nof_ul_symbols.has_value(); + const bool is_tdd = params.nof_ul_symbols_p1.has_value(); cell_config_builder_params cell_params = {.dl_f_ref_arfcn = not is_tdd ? 365000U : 520002U}; if (is_tdd) { auto& tdd_cfg = cell_params.tdd_ul_dl_cfg_common.emplace(); @@ -801,24 +821,19 @@ static cell_config_builder_params make_cell_cfg_params(const srs_params& params) tdd_cfg.pattern1.nof_dl_slots = 7; tdd_cfg.pattern1.nof_dl_symbols = 2; tdd_cfg.pattern1.nof_ul_slots = 2; - tdd_cfg.pattern1.nof_ul_symbols = params.nof_ul_symbols.value(); + tdd_cfg.pattern1.nof_ul_symbols = params.nof_ul_symbols_p1.value(); + tdd_cfg.ref_scs = subcarrier_spacing::kHz30; } return cell_params; } -static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& params) +static du_cell_config make_srs_base_du_cell_config(const cell_config_builder_params& params) { + // This function generates a configuration which would potentially allow for very large number of SRS resources. du_cell_config du_cfg = config_helpers::make_default_du_cell_config(params); auto& srs_cfg = du_cfg.srs_cfg; - auto& tdd_cfg = du_cfg.tdd_ul_dl_cfg_common.emplace(); - tdd_cfg.pattern1.dl_ul_tx_period_nof_slots = 10; - tdd_cfg.pattern1.nof_dl_slots = 7; - tdd_cfg.pattern1.nof_dl_symbols = 8; - tdd_cfg.pattern1.nof_ul_slots = 2; - tdd_cfg.pattern1.nof_ul_symbols = 4; - // Generates a random SRS configuration. srs_cfg.tx_comb = test_rgen::bernoulli(0.5) ? tx_comb_size::n2 : tx_comb_size::n4; srs_cfg.max_nof_symbols = test_rgen::uniform_int(1U, 6U); @@ -828,6 +843,7 @@ static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& while (srs_cfg.nof_symbols > srs_cfg.max_nof_symbols) { srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; } + // The TX comb cyclic shift value depends on the TX comb size. if (srs_cfg.tx_comb == srsran::tx_comb_size::n2) { std::array srs_cyclic_shift_values = { @@ -850,11 +866,14 @@ static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& srs_seq_id_values[test_rgen::uniform_int(0, srs_seq_id_values.size() - 1)]; if (du_cfg.tdd_ul_dl_cfg_common.has_value()) { - std::array period_values = {srs_periodicity::sl10, + std::array period_values = {srs_periodicity::sl10, srs_periodicity::sl20, srs_periodicity::sl40, srs_periodicity::sl80, - srs_periodicity::sl160}; + srs_periodicity::sl160, + srs_periodicity::sl320, + srs_periodicity::sl640, + srs_periodicity::sl1280}; srs_cfg.srs_period.emplace(period_values[test_rgen::uniform_int(0, period_values.size() - 1)]); } else { std::array period_values = {srs_periodicity::sl1, @@ -873,12 +892,67 @@ static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& return du_cfg; } +static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& params, bool limit_srs_res) +{ + auto du_cfg = make_srs_base_du_cell_config(params); + + // For the optimality test, we to have a configuration that doesn't allow more than 1024 SRS resources. + if (not limit_srs_res) { + return du_cfg; + } + + // This function calculates the total number of SRS resources that can be potentially allocated in the cell with the + // given SRS parameters. + auto tot_num_srs_res = [&du_cfg]() { + auto& tdd_cfg = du_cfg.tdd_ul_dl_cfg_common; + auto& srs_cfg = du_cfg.srs_cfg; + // This is the number of SRS resources per symbol interval. + const unsigned nof_res_per_symb_interval = srs_cfg.sequence_id_reuse_factor * + static_cast(srs_cfg.cyclic_shift_reuse_factor) * + static_cast(srs_cfg.tx_comb); + + // A symbol interval is an interval where the SRS resource can be placed within a slot and its width (or length) is + // given by the corresponding SRS parameter \c nof_symb in the SRS configuration. This "number of symbols intervals" + // counts all the symbols intervals within the SRS period. + unsigned nof_symb_intervals = 0; + + // The number of symbols interval per slot depends on whether it's FDD or TDD. + if (not tdd_cfg.has_value()) { + // In FDD, in an SRS period we can "max_nof_symbols / nof_symbols" intervals per slot. + nof_symb_intervals = srs_cfg.max_nof_symbols.to_uint() / static_cast(srs_cfg.nof_symbols) * + static_cast(srs_cfg.srs_period.value()); + } else { + // In TDD, in an SRS period we can "max_nof_symbols / nof_symbols" intervals per UL slot; in addition to this, the + // partially-UL slots can have extra symbols intervals, up to a maximum of 6U, which is the max number of symbols + // usable for SRS resources. + nof_symb_intervals = + (srs_cfg.max_nof_symbols.to_uint() / static_cast(srs_cfg.nof_symbols)) * + tdd_cfg->pattern1.nof_ul_slots * + (static_cast(srs_cfg.srs_period.value()) / tdd_cfg->pattern1.dl_ul_tx_period_nof_slots); + if (tdd_cfg->pattern1.nof_ul_symbols != 0) { + nof_symb_intervals += + (std::min(tdd_cfg->pattern1.nof_ul_symbols, srs_cfg.max_nof_symbols.max()) / + static_cast(srs_cfg.nof_symbols)) * + (static_cast(srs_cfg.srs_period.value()) / tdd_cfg->pattern1.dl_ul_tx_period_nof_slots); + } + } + + return nof_symb_intervals * nof_res_per_symb_interval; + }; + + while (tot_num_srs_res() > static_cast(MAX_NOF_DU_UES)) { + du_cfg = make_srs_base_du_cell_config(params); + } + + return du_cfg; +} + class du_srs_resource_manager_tester : public ::testing::TestWithParam { protected: explicit du_srs_resource_manager_tester(cell_config_builder_params params_ = make_cell_cfg_params(GetParam())) : params(params_), - cell_cfg_list({make_srs_du_cell_config(params_)}), + cell_cfg_list({make_srs_du_cell_config(params_, GetParam().test_optimality)}), srs_params(cell_cfg_list[0].srs_cfg), du_srs_res_mng(cell_cfg_list) { @@ -899,7 +973,11 @@ class du_srs_resource_manager_tester : public ::testing::TestWithParaminit_ul_bwp.srs_cfg.reset(); + + bool res = du_srs_res_mng.alloc_resources(ue); + if (res) { return ue; } // If the allocation was not possible, remove the UE. @@ -907,6 +985,7 @@ class du_srs_resource_manager_tester : public ::testing::TestWithParaminit_ul_bwp.srs_cfg.has_value()); const auto& ue_srs_config = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); // Verify first the SRS resource set list. @@ -1085,7 +1170,7 @@ TEST_P(du_srs_resource_manager_tester, srs_resources_parameters_are_valid) // Verify the symbols, depending on whether it's FDD, or TDD. ASSERT_EQ(srs_res.res_mapping.nof_symb, srs_params.nof_symbols); if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value() and - is_partually_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { + is_partially_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { ASSERT_LT(srs_res.res_mapping.start_pos, cell_cfg_list[0].tdd_ul_dl_cfg_common.value().pattern1.nof_ul_symbols); } else { ASSERT_LT(srs_res.res_mapping.start_pos, srs_params.max_nof_symbols.to_uint()); @@ -1095,12 +1180,289 @@ TEST_P(du_srs_resource_manager_tester, srs_resources_parameters_are_valid) INSTANTIATE_TEST_SUITE_P(test_du_srs_res_mng_for_different_ul_symbols, du_srs_resource_manager_tester, - ::testing::Values(srs_params{.nof_ul_symbols = std::nullopt}, - srs_params{.nof_ul_symbols = 0U}, - srs_params{.nof_ul_symbols = 1U}, - srs_params{.nof_ul_symbols = 2U}, - srs_params{.nof_ul_symbols = 3U}, - srs_params{.nof_ul_symbols = 4U}, - srs_params{.nof_ul_symbols = 5U}, - srs_params{.nof_ul_symbols = 6U}, - srs_params{.nof_ul_symbols = 7U})); + ::testing::Values(srs_params{.nof_ul_symbols_p1 = std::nullopt}, + srs_params{.nof_ul_symbols_p1 = 0U}, + srs_params{.nof_ul_symbols_p1 = 1U}, + srs_params{.nof_ul_symbols_p1 = 2U}, + srs_params{.nof_ul_symbols_p1 = 3U}, + srs_params{.nof_ul_symbols_p1 = 4U}, + srs_params{.nof_ul_symbols_p1 = 5U}, + srs_params{.nof_ul_symbols_p1 = 6U}, + srs_params{.nof_ul_symbols_p1 = 7U}), + [](const testing::TestParamInfo& params_item) { + return fmt::format("{}", params_item.param); + }); + +///////// Test the optimality of DU SRS resource manager policy ///////// + +class du_srs_resource_manager_tester_optimality : public du_srs_resource_manager_tester +{ +protected: + explicit du_srs_resource_manager_tester_optimality() + { + nof_srs_res_per_symb_interval = static_cast(srs_params.tx_comb) * + static_cast(srs_params.cyclic_shift_reuse_factor) * + static_cast(srs_params.sequence_id_reuse_factor); + srs_res_tracker.reserve(static_cast(srs_params.srs_period.value())); + + // Build the SRS resource tracker. + for (unsigned offset = 0; offset != static_cast(srs_params.srs_period.value()); ++offset) { + if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value()) { + const auto& tdd_cfg = cell_cfg_list[0].tdd_ul_dl_cfg_common.value(); + + if (not is_ul_slot(offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { + // In TDD, no SRS resources can be allocated in DL slots. + srs_res_tracker.emplace_back(0U); + } else if (is_partially_ul_slot(offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + const unsigned nof_ul_symbols = + srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); + // The number of symbols intervals is limited by the number of symbols where the SRS can be placed. + const unsigned nof_intervals = std::min(nof_ul_symbols / static_cast(srs_params.nof_symbols), + srs_params.max_nof_symbols.max()); + srs_res_tracker.emplace_back(nof_intervals); + } else { + const unsigned nof_intervals = + srs_params.max_nof_symbols.to_uint() / static_cast(srs_params.nof_symbols); + srs_res_tracker.emplace_back(nof_intervals); + } + } + // FDD case. + else { + const unsigned nof_intervals = + srs_params.max_nof_symbols.to_uint() / static_cast(srs_params.nof_symbols); + srs_res_tracker.emplace_back(nof_intervals); + } + } + } + + // Helper struct that keeps track of the number of SRS resources per symbol interval for a given offset. + struct res_per_slot_tracker { + explicit res_per_slot_tracker(unsigned nof_srs_symb_intervals_per_slot_) : + nof_srs_symb_intervals_per_slot(nof_srs_symb_intervals_per_slot_) + { + // Initialize the vector with zeros, as at the beginning no SRS resources have been allocated. + res_per_symb_interval.assign(nof_srs_symb_intervals_per_slot, 0U); + } + + const unsigned nof_srs_symb_intervals_per_slot; + // This vector keeps track of the number of SRS resources per symbol interval. The symbol interval with index 0 is + // the last one in the slot; the symbol interval with index 1 is the second to last, and so on. + std::vector res_per_symb_interval; + }; + + // The number of SRS resources per symbol interval, which depends on the TX comb size, on the cyclic shift reuse + // factor, and on the sequence ID reuse factor. + unsigned nof_srs_res_per_symb_interval = 0; + // This vector keeps track of the number of SRS resources per symbol interval for each offset. + std::vector srs_res_tracker; + + // Save the SRS resource allocation in the tracker. + void track_srs_res_alloc(const srs_config::srs_resource& srs_res) + { + srsran_assert(srs_res.periodicity_and_offset.has_value(), "SRS resource must have a periodicity and offset"); + const unsigned srs_offset = srs_res.periodicity_and_offset->offset; + const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); + srsran_assert(interval_idx < srs_res_tracker[srs_offset].res_per_symb_interval.size(), + "SRS resource must have a periodicity and offset"); + ++srs_res_tracker[srs_offset].res_per_symb_interval[interval_idx]; + } + + // Check if there is any partially-UL slot that has not completely filled with SRS resources. + bool has_free_partial_ul_slots() + { + for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { + if (not is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value())) { + continue; + } + if (std::any_of(srs_res_tracker[n].res_per_symb_interval.begin(), + srs_res_tracker[n].res_per_symb_interval.end(), + [this](unsigned cnt) { return cnt < nof_srs_res_per_symb_interval; })) { + return true; + } + } + return false; + } + + // Check if all the symbol intervals with index lower than the one of the given SRS resource have + // been used (in fully-UL slots). + bool all_lower_intervals_used(const srs_config::srs_resource& srs_res) + { + const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); + if (interval_idx == 0) { + return true; + } + + for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { + if (params.tdd_ul_dl_cfg_common.has_value() and (not is_ul_slot(n, params.tdd_ul_dl_cfg_common.value()) or + is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value()))) { + continue; + } + if (std::any_of(srs_res_tracker[n].res_per_symb_interval.begin(), + srs_res_tracker[n].res_per_symb_interval.begin() + interval_idx, + [this](unsigned cnt) { return cnt < nof_srs_res_per_symb_interval; })) { + return false; + } + } + return true; + } + + // Check if there is any symbol interval of the same index of the one of the given SRS resource that is not empty, but + // not full either. + bool non_empty_non_full_interval(const srs_config::srs_resource& srs_res) + { + const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); + for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { + // Skip the slot where the SRS resource has been allocated, otherwise this will always return true. + if (n == srs_res.periodicity_and_offset->offset) { + continue; + } + if (params.tdd_ul_dl_cfg_common.has_value() and (not is_ul_slot(n, params.tdd_ul_dl_cfg_common.value()) or + is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value()))) { + continue; + } + srsran_assert(interval_idx < srs_res_tracker[n].res_per_symb_interval.size(), + "Interval index exceeds the size of the vector"); + if (srs_res_tracker[n].res_per_symb_interval[interval_idx] > 0U and + srs_res_tracker[n].res_per_symb_interval[interval_idx] < nof_srs_res_per_symb_interval) { + return true; + } + } + return false; + } +}; + +TEST_P(du_srs_resource_manager_tester_optimality, srs_are_assigned_according_to_class_policy) +{ + // > Created UEs have unique SRS resources. + for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { + std::optional ue = add_ue(to_du_ue_index(i)); + if (not ue.has_value()) { + break; + } + + // Verify all parameters of the SRS resource are as expected. + ASSERT_TRUE(ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); + const auto& ue_srs_config = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + const auto& srs_res = ue_srs_config.srs_res_list[0]; + + // Save the SRS resource allocation in the tracker. + track_srs_res_alloc(srs_res); + + // The SRS allocation assigns resources according to the policy: + // - If there is a partially-UL slot available, then the SRS resources are allocated in the partially-UL slots. + // - If there are no partially-UL slots, then the SRS resources are allocated in the fully-UL slots. + // - If there are no fully-UL slots with a symbol interval of index i available, then the SRS resources are + // allocated in a symbol interval of index i+1, in any slot. + // - If there is a fully-UL slots with a symbol interval of index i available that has already SRS resources + // allocated, but has not been completely filled, then the SRS resources are allocated in that slot. + if (params.tdd_ul_dl_cfg_common.has_value()) { + if (not is_partially_ul_slot(srs_res.periodicity_and_offset.value().offset, + params.tdd_ul_dl_cfg_common.value())) { + ASSERT_FALSE(has_free_partial_ul_slots()); + ASSERT_TRUE(all_lower_intervals_used(srs_res)); + ASSERT_FALSE(non_empty_non_full_interval(srs_res)); + } + } else { + ASSERT_TRUE(all_lower_intervals_used(srs_res)); + ASSERT_FALSE(non_empty_non_full_interval(srs_res)); + } + } +} + +INSTANTIATE_TEST_SUITE_P(test_du_srs_res_mng_for_different_ul_symbols, + du_srs_resource_manager_tester_optimality, + ::testing::Values(srs_params{.nof_ul_symbols_p1 = std::nullopt, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 0U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 1U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 2U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 3U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 4U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 5U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 6U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 7U, .test_optimality = true}), + [](const testing::TestParamInfo& params_item) { + return fmt::format("{}", params_item.param); + }); + +///////// Test the DU RAN resource manager for both PUCCH and SRS resources ///////// + +// This helper builds a DU cell configuration with a custom PUCCH and SRS configuration. The input parameter +// pucch_has_more_res_than_srs indicates whether the PUCCH or SRS configuration allows more resources than the other. +// This way, we can test the allocation and de-allocation of resources when the DU rejects a UE due to lack of PUCCH or +// SRS resources. +static du_cell_config make_custom_pucch_srs_du_cell_config(bool pucch_has_more_res_than_srs) +{ + du_cell_config du_cfg = config_helpers::make_default_du_cell_config(); + auto& pucch_params = du_cfg.pucch_cfg; + pucch_params.nof_ue_pucch_f0_or_f1_res_harq = 6U; + pucch_params.nof_ue_pucch_f2_res_harq = 6U; + pucch_params.nof_sr_resources = pucch_has_more_res_than_srs ? 10U : 1U; + pucch_params.nof_csi_resources = pucch_has_more_res_than_srs ? 10U : 1U; + pucch_params.nof_cell_harq_pucch_res_sets = 1U; + auto& f1_params = std::get(pucch_params.f0_or_f1_params); + f1_params.nof_cyc_shifts = nof_cyclic_shifts::no_cyclic_shift; + f1_params.occ_supported = false; + + auto& tdd_cfg = du_cfg.tdd_ul_dl_cfg_common.emplace(); + tdd_cfg.pattern1.dl_ul_tx_period_nof_slots = 10; + tdd_cfg.pattern1.nof_dl_slots = 7; + tdd_cfg.pattern1.nof_dl_symbols = 10; + tdd_cfg.pattern1.nof_ul_slots = 2; + tdd_cfg.pattern1.nof_ul_symbols = 0; + + du_cfg.ue_ded_serv_cell_cfg.ul_config.value().init_ul_bwp.pucch_cfg.value().sr_res_list.front().period = + srsran::sr_periodicity::sl_10; + + auto& srs_cfg = du_cfg.srs_cfg; + + // Generates a random SRS configuration. + srs_cfg.tx_comb = tx_comb_size::n2; + srs_cfg.max_nof_symbols = 1U; + srs_cfg.nof_symbols = srs_nof_symbols::n1; + srs_cfg.cyclic_shift_reuse_factor = nof_cyclic_shifts::no_cyclic_shift; + srs_cfg.sequence_id_reuse_factor = 1U; + srs_cfg.srs_period.emplace(du_cfg.tdd_ul_dl_cfg_common.has_value() ? srs_periodicity::sl10 : srs_periodicity::sl1); + + pucch_params.max_nof_symbols = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_cfg.max_nof_symbols.to_uint(); + f1_params.nof_symbols = std::min(f1_params.nof_symbols.to_uint(), pucch_params.max_nof_symbols.to_uint()); + + return du_cfg; +} + +class du_ran_res_mng_pucch_srs_tester : public du_ran_resource_manager_tester_base, + public ::testing::TestWithParam +{ +protected: + explicit du_ran_res_mng_pucch_srs_tester() : + du_ran_resource_manager_tester_base(cell_config_builder_params{}, make_custom_pucch_srs_du_cell_config(GetParam())) + { + srsran_assert(default_ue_cell_cfg.csi_meas_cfg.has_value() and + not default_ue_cell_cfg.csi_meas_cfg.value().csi_report_cfg_list.empty() and + std::holds_alternative( + default_ue_cell_cfg.csi_meas_cfg.value().csi_report_cfg_list[0].report_cfg_type), + "CSI report configuration is required for this unittest;"); + } +}; + +TEST_P(du_ran_res_mng_pucch_srs_tester, when_alloc_fail_ue_has_no_srs_and_no_pucch_cfgs) +{ + // This tests how the DU handles the RAN resource allocation failure due to lack of PUCCH or SRS resources. + for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { + du_ue_index_t next_ue_index = to_du_ue_index(i); + const ue_ran_resource_configurator* ue_res = create_ue(next_ue_index); + ASSERT_NE(ue_res, nullptr); + if (ue_res->resource_alloc_failed()) { + ASSERT_FALSE(ue_res->value().cell_group.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.pucch_cfg.has_value()); + ASSERT_TRUE(ue_res->value().cell_group.cells[0].serv_cell_cfg.csi_meas_cfg->csi_report_cfg_list.empty()); + ASSERT_FALSE(ue_res->value().cell_group.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); + break; + } else { + ASSERT_TRUE(ue_res->value().cell_group.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.pucch_cfg.has_value()); + ASSERT_FALSE(ue_res->value().cell_group.cells[0].serv_cell_cfg.csi_meas_cfg->csi_report_cfg_list.empty()); + ASSERT_TRUE(ue_res->value().cell_group.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); + } + } +} + +INSTANTIATE_TEST_SUITE_P(different_f1_f2_resources, du_ran_res_mng_pucch_srs_tester, ::testing::Values(true, false)); From cb1863616c45a02b85eb4e2c96caeb28a07e195d Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 26 Sep 2024 14:13:47 +0200 Subject: [PATCH 172/174] du: simplify optimization fnc in srs res mng Signed-off-by: Carlo Galiotto --- .../du_pucch_resource_manager.cpp | 2 +- .../du_srs_resource_manager.cpp | 45 ++++++++++--------- .../du_srs_resource_manager.h | 36 +++++++++------ .../du_ran_resource_manager_test.cpp | 20 ++++----- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp index 25fb1cec46..45aa75a42c 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_pucch_resource_manager.cpp @@ -350,7 +350,7 @@ void du_pucch_resource_manager::dealloc_resources(cell_group_config& cell_grp_cf } // Disable the PUCCH configuration in this UE. This makes sure the DU will exit this function immediately when it gets - // call again for the same UE (upon destructor's call). + // called again for the same UE (upon destructor's call). disable_pucch_cfg(cell_grp_cfg); } diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index c4c836c4a8..b9dd70b8f5 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -57,7 +57,8 @@ static std::optional compute_srs_bw_param(unsigned nof_ul_rbs) // are placed at the center of the band. static unsigned compute_freq_shift(unsigned c_srs, unsigned nof_ul_rbs) { - // As per Section 6.4.1.4.3, the parameter \f$C_{SRS}\f$ = 0 provides the bandwidth of the SRS resources. + // As per Section 6.4.1.4.3, the parameter \f$m_{SRS}\f$ = 0 is an index that, along with \f$C_{SRS}\f$, maps to the + // bandwidth of the SRS resources. constexpr uint8_t b_srs_0 = 0; std::optional srs_params = srs_configuration_get(c_srs, b_srs_0); srsran_sanity_check(srs_params.has_value() and nof_ul_rbs >= srs_params.value().m_srs, @@ -137,8 +138,12 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell cell.cell_srs_res_list = generate_cell_srs_list(cell.cell_cfg); const auto srs_period_slots = static_cast(cell.cell_cfg.srs_cfg.srs_period.value()); - cell.slot_resource_cnt.reserve(srs_period_slots); + // Reserve the size of the vector and set the SRS counter of each offset to 0. + cell.slot_resource_cnt.assign(srs_period_slots, 0U); cell.srs_res_offset_free_list.reserve(du_srs_policy_max_ul_th::cell_context::max_nof_srs_res); + cell.nof_res_per_symb_interval = static_cast(cell.cell_cfg.srs_cfg.tx_comb) * + static_cast(cell.cell_cfg.srs_cfg.cyclic_shift_reuse_factor) * + static_cast(cell.cell_cfg.srs_cfg.sequence_id_reuse_factor); for (unsigned offset = 0; offset != srs_period_slots; ++offset) { // We don't generate more than the maximum number of SRS resources per cell. @@ -146,11 +151,9 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell break; } - unsigned offset_res_cnt = 0U; // Verify whether the offset maps to a partially- or fully-UL slot. if (cell_cfg_list_[0].tdd_ul_dl_cfg_common.has_value() and not is_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { - cell.slot_resource_cnt.emplace_back(0U, offset_res_cnt); continue; } @@ -164,6 +167,8 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell if (is_partually_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + // As per Section 6.4.1.4.1, TS 38.211, the SRS resources can only be placed in the last 6 symbols of the + // slot. static constexpr unsigned max_srs_symbols = 6U; const unsigned nof_ul_symbols_for_srs = std::min(srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(), @@ -185,9 +190,7 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell } } cell.srs_res_offset_free_list.emplace_back(res.cell_res_id, offset); - ++offset_res_cnt; } - cell.slot_resource_cnt.emplace_back(0U, offset_res_cnt); } } } @@ -208,8 +211,8 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) return true; } - // The UE SRS configuration is taken from a base configuration, saved in the GNB. The details that are - // UE specific will be added later on in this function. + // The UE SRS configuration is taken from a base configuration, saved in the GNB. The UE specific parameters will be + // added later on in this function. cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].default_srs_cfg); srs_config& ue_srs_cfg = cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); @@ -222,7 +225,7 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) return false; } - // Find the best resource ID and offset for this UE. + // Find the best resource ID and offset for this UE, according to the class policy. auto srs_res_id_offset = cells[0].find_optimal_ue_srs_resource(); if (srs_res_id_offset == free_srs_list.end()) { @@ -278,8 +281,8 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) // Remove the allocated SRS resource from the free list. free_srs_list.erase(srs_res_id_offset); - // Update the used_not_full slot vector. - ++cells[0].slot_resource_cnt[srs_offset].first; + // Update the SRS resource per slot counter. + ++cells[0].slot_resource_cnt[srs_offset]; return true; } @@ -287,13 +290,14 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) std::vector>::const_iterator du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() { - // The weights assigned here can be set to any value, as long as: + // The weights assigned here can be set to arbitrarily value, as long as: // - symbol_weight_base is greater than 0; - // - reuse_slot_discount less than symbol_weight_base; - // - max_weight is > symbol_weight_base * (srs_builder_params::max_nof_symbols / - // srs_builder_params::nof_symbols). + // - reuse_slot_discount is less than symbol_weight_base; + // - max_weight > symbol_weight_base * (srs_builder_params::max_nof_symbols / srs_builder_params::nof_symbols). static constexpr unsigned max_weight = 100U; static constexpr unsigned symbol_weight_base = 10U; + // We give a discount to the symbol weight if the offset is already used but not full. + static const unsigned partial_symb_interval_discount = symbol_weight_base / 2U; const auto weight_function = [&](const pair_res_id_offset& srs_res) { if (cell_cfg.tdd_ul_dl_cfg_common.has_value() and @@ -308,7 +312,7 @@ du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() return max_weight; } - // Give priority to the last symbols within a slot. This reduces the space used for the SRS in a slot. + // Give priority to the last symbol intervals within a slot. This reduces the space used for the SRS in a slot. const unsigned symb_weight = symbol_weight_base * ((NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res_cfg_it->symbols.start()) / srs_res_cfg_it->symbols.length()); @@ -316,7 +320,8 @@ du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() // We consider a discount if the offset is already used but not full; this way, we give an incentive // to the SRS resources not to be allocated on a new slot, to avoid taking PUSCH symbols on a new // slot. - const unsigned reuse_slot_discount = offset_used_not_full(srs_res.second) ? symbol_weight_base / 2U : 0U; + const unsigned reuse_slot_discount = + offset_interval_used_not_full(srs_res.second) ? partial_symb_interval_discount : 0U; return symb_weight - reuse_slot_discount; }; @@ -346,11 +351,11 @@ void du_srs_policy_max_ul_th::dealloc_resources(cell_group_config& cell_grp_cfg) free_srs_list.emplace_back(srs_res.id.cell_res_id, offset_to_deallocate); // Update the used_not_full slot vector. - srsran_assert(cells[0].slot_resource_cnt[offset_to_deallocate].first != 0, "The offset is expected to be non-zero"); - --cells[0].slot_resource_cnt[offset_to_deallocate].first; + srsran_assert(cells[0].slot_resource_cnt[offset_to_deallocate] != 0, "The offset is expected to be non-zero"); + --cells[0].slot_resource_cnt[offset_to_deallocate]; } // Reset the SRS configuration in this UE. This makes sure the DU will exit this function immediately when it gets - // call again for the same UE (upon destructor's call). + // called again for the same UE (upon destructor's call). cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); } diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h index 433bbddf9c..4866ea0831 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h @@ -37,14 +37,20 @@ class du_srs_resource_manager }; /// This class implements the MAX UL throughput policy for the SRS allocation. The SRS resources are allocated with the -/// objective to minimize the number of slots that contains the SRS resources; furthermore, within a given slot, the SRS -/// resources are allocated to minimize the number of symbols that are used for SRS. The drawback of this policy is that -/// it can increase the inter slot SRS interference among different UEs. +/// objective to minimize the number of slots and symbols that contain the SRS resources, to reduce as much as possible +/// the slots and symbols resources taken from the PUSCH. The drawback of this policy is that it can increase the +/// inter-slot SRS interference among different UEs. class du_srs_policy_max_ul_th : public du_srs_resource_manager { public: explicit du_srs_policy_max_ul_th(span cell_cfg_list_); + /// The SRS resources are allocate according to the following policy: + /// - Give priority to resources that are placed on partially-UL slots, first. + /// - Then, give priority to SRS resources that is placed on the symbol interval (i.e, the symbols interval used by an + /// SRS resource) closest to the end of the slot. + /// - If a symbol interval on a particular slot is already used and not completely full, then give priority to this + /// symbol interval over any other symbol intervals on the same or on different slots. bool alloc_resources(cell_group_config& cell_grp_cfg) override; void dealloc_resources(cell_group_config& cell_grp_cfg) override; @@ -53,8 +59,6 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager struct cell_context { cell_context(const du_cell_config& cfg); - using pair_res_id_offset = std::pair; - // Returns the DU SRS resource with the given cell resource ID from the cell list of resources. std::vector::const_iterator get_du_srs_res_cfg(unsigned cell_res_id) { @@ -65,15 +69,22 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager return cell_srs_res_list.cbegin() + cell_res_id; } + using pair_res_id_offset = std::pair; + // Returns the best SRS resource ID and offset for this UE, according to the policy defined in this class. std::vector::const_iterator find_optimal_ue_srs_resource(); - // Check if this SRS offset has already some SRS resources allocated, but can still host more. - bool offset_used_not_full(unsigned offset) const + // Check if this SRS offset has already some SRS resources allocated at a given symbol interval, but can still host + // more. + bool offset_interval_used_not_full(unsigned offset) const { + // The counter of SRS resources counts how many resources have been allocated in the current slot (offset). + // If the counter is 0, then the offset is free. + // If the counter is a non-zero multiple (i.e, N) of nof_res_per_symb_interval, then the symbol interval of index + // N-1 has been filled completely and the next symbol interval of index N is free. In any other case, the symbol + // interval N-1 is partially filled. srsran_assert(offset < slot_resource_cnt.size(), "Offset out of range"); - return slot_resource_cnt[offset].first != 0 and - slot_resource_cnt[offset].first < slot_resource_cnt[offset].second; + return slot_resource_cnt[offset] % nof_res_per_symb_interval != 0U; } // Parameters that are common to all cell SRS resources. @@ -82,8 +93,6 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager unsigned freq_shift; }; - using pair_cnt_max = std::pair; - // Maximum number of SRS resources that can be generated in a cell. // [Implementation-defined] We assume each UE has one and only one resource. static const unsigned max_nof_srs_res = MAX_NOF_DU_UES; @@ -96,8 +105,9 @@ class du_srs_policy_max_ul_th : public du_srs_resource_manager std::vector cell_srs_res_list; // List of SRS resource ID and offset that can be allocated to the cell's UEs. std::vector srs_res_offset_free_list; - // Counter of how many SRS resources (current counter, max_counter) that can be allocated in the same slot (offset). - std::vector slot_resource_cnt; + unsigned nof_res_per_symb_interval = 0; + // Counter of how many SRS resources that are allocated per slot (offset). + std::vector slot_resource_cnt; }; // Contains the resources for the different cells of the DU. diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index 25c7a8107c..f2ded3c76d 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -830,14 +830,13 @@ static cell_config_builder_params make_cell_cfg_params(const srs_params& params) static du_cell_config make_srs_base_du_cell_config(const cell_config_builder_params& params) { - // This function generates a configuration which would potentially allow for very large number of SRS resources. + // This function generates a configuration which would potentially allow for a very large number of SRS resources. du_cell_config du_cfg = config_helpers::make_default_du_cell_config(params); auto& srs_cfg = du_cfg.srs_cfg; // Generates a random SRS configuration. - srs_cfg.tx_comb = test_rgen::bernoulli(0.5) ? tx_comb_size::n2 : tx_comb_size::n4; - srs_cfg.max_nof_symbols = test_rgen::uniform_int(1U, 6U); - // The number of SRS symbols cannot exceed the number of + srs_cfg.tx_comb = test_rgen::bernoulli(0.5) ? tx_comb_size::n2 : tx_comb_size::n4; + srs_cfg.max_nof_symbols = test_rgen::uniform_int(1U, 6U); std::array nof_symb_values = {srs_nof_symbols::n1, srs_nof_symbols::n2, srs_nof_symbols::n4}; srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; while (srs_cfg.nof_symbols > srs_cfg.max_nof_symbols) { @@ -896,7 +895,7 @@ static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& { auto du_cfg = make_srs_base_du_cell_config(params); - // For the optimality test, we to have a configuration that doesn't allow more than 1024 SRS resources. + // For the optimality test, we to have a configuration that doesn't allow for more than 1024 SRS resources. if (not limit_srs_res) { return du_cfg; } @@ -906,14 +905,14 @@ static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& auto tot_num_srs_res = [&du_cfg]() { auto& tdd_cfg = du_cfg.tdd_ul_dl_cfg_common; auto& srs_cfg = du_cfg.srs_cfg; - // This is the number of SRS resources per symbol interval. + // This is the number of SRS resources per symbol interval. A symbol interval is an interval where the SRS resource + // can be placed within a slot and its width (or length) is given by the corresponding SRS parameter \c nof_symb in + // the SRS configuration. const unsigned nof_res_per_symb_interval = srs_cfg.sequence_id_reuse_factor * static_cast(srs_cfg.cyclic_shift_reuse_factor) * static_cast(srs_cfg.tx_comb); - // A symbol interval is an interval where the SRS resource can be placed within a slot and its width (or length) is - // given by the corresponding SRS parameter \c nof_symb in the SRS configuration. This "number of symbols intervals" - // counts all the symbols intervals within the SRS period. + // This "number of symbols intervals" counts all the symbols intervals within the SRS period. unsigned nof_symb_intervals = 0; // The number of symbols interval per slot depends on whether it's FDD or TDD. @@ -937,6 +936,7 @@ static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& } } + // Return the total number of SRS resources. return nof_symb_intervals * nof_res_per_symb_interval; }; @@ -1046,7 +1046,7 @@ class du_srs_resource_manager_tester : public ::testing::TestWithParam Date: Fri, 27 Sep 2024 15:42:31 +0200 Subject: [PATCH 173/174] du: move du srs res mng unittest to separate file Signed-off-by: Carlo Galiotto --- .../du_ran_resource_manager_impl.cpp | 7 +- .../du_srs_resource_manager.cpp | 14 +- .../du_srs_resource_manager.h | 4 +- tests/unittests/du_manager/CMakeLists.txt | 7 +- .../du_ran_resource_manager_test.cpp | 2 +- .../du_srs_resource_manager_test.cpp | 614 ++++++++++++++++++ 6 files changed, 634 insertions(+), 14 deletions(-) create mode 100644 tests/unittests/du_manager/du_srs_resource_manager_test.cpp diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp index 74eda4f195..019360ae3d 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_ran_resource_manager_impl.cpp @@ -38,7 +38,8 @@ du_ue_ran_resource_updater_impl::update(du_cell_index_t pc /////////////////////////// -static void initialize_serv_cell_cfg(serving_cell_config& serv_cell_cfg) +// Helper that resets the PUCCH and SRS configurations in the serving cell configuration. +static void reset_serv_cell_cfg(serving_cell_config& serv_cell_cfg) { srsran_assert(serv_cell_cfg.ul_config.has_value() and serv_cell_cfg.ul_config.value().init_ul_bwp.pucch_cfg.has_value() and @@ -63,7 +64,7 @@ du_ran_resource_manager_impl::du_ran_resource_manager_impl(span(cell_cfg_list)) + srs_res_mng(std::make_unique(cell_cfg_list)) { } @@ -180,7 +181,7 @@ error_type du_ran_resource_manager_impl::allocate_cell_resources(du // Start with removing PUCCH and SRS configurations. This step simplifies the handling of the allocation failure // path. - initialize_serv_cell_cfg(ue_res.cell_group.cells[0].serv_cell_cfg); + reset_serv_cell_cfg(ue_res.cell_group.cells[0].serv_cell_cfg); if (not srs_res_mng->alloc_resources(ue_res.cell_group)) { // Deallocate dedicated Search Spaces. diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index b9dd70b8f5..6d8750b031 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -114,10 +114,10 @@ static srs_config build_default_srs_cfg(const du_cell_config& default_cell_cfg) return srs_cfg; } -du_srs_policy_max_ul_th::cell_context::cell_context(const du_cell_config& cfg) : +du_srs_policy_max_ul_rate::cell_context::cell_context(const du_cell_config& cfg) : cell_cfg(cfg), default_srs_cfg(build_default_srs_cfg(cfg)){}; -du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell_cfg_list_) : +du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span cell_cfg_list_) : cells(cell_cfg_list_.begin(), cell_cfg_list_.end()) { for (auto& cell : cells) { @@ -140,14 +140,14 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell const auto srs_period_slots = static_cast(cell.cell_cfg.srs_cfg.srs_period.value()); // Reserve the size of the vector and set the SRS counter of each offset to 0. cell.slot_resource_cnt.assign(srs_period_slots, 0U); - cell.srs_res_offset_free_list.reserve(du_srs_policy_max_ul_th::cell_context::max_nof_srs_res); + cell.srs_res_offset_free_list.reserve(du_srs_policy_max_ul_rate::cell_context::max_nof_srs_res); cell.nof_res_per_symb_interval = static_cast(cell.cell_cfg.srs_cfg.tx_comb) * static_cast(cell.cell_cfg.srs_cfg.cyclic_shift_reuse_factor) * static_cast(cell.cell_cfg.srs_cfg.sequence_id_reuse_factor); for (unsigned offset = 0; offset != srs_period_slots; ++offset) { // We don't generate more than the maximum number of SRS resources per cell. - if (cell.srs_res_offset_free_list.size() >= du_srs_policy_max_ul_th::cell_context::max_nof_srs_res) { + if (cell.srs_res_offset_free_list.size() >= du_srs_policy_max_ul_rate::cell_context::max_nof_srs_res) { break; } @@ -195,7 +195,7 @@ du_srs_policy_max_ul_th::du_srs_policy_max_ul_th(span cell } } -bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) +bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg) { // TODO: Adapt this to the case of UEs with multiple cells configs. srsran_assert( @@ -288,7 +288,7 @@ bool du_srs_policy_max_ul_th::alloc_resources(cell_group_config& cell_grp_cfg) } std::vector>::const_iterator -du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() +du_srs_policy_max_ul_rate::cell_context::find_optimal_ue_srs_resource() { // The weights assigned here can be set to arbitrarily value, as long as: // - symbol_weight_base is greater than 0; @@ -336,7 +336,7 @@ du_srs_policy_max_ul_th::cell_context::find_optimal_ue_srs_resource() return optimal_res_it; } -void du_srs_policy_max_ul_th::dealloc_resources(cell_group_config& cell_grp_cfg) +void du_srs_policy_max_ul_rate::dealloc_resources(cell_group_config& cell_grp_cfg) { if (not cells[0].cell_cfg.srs_cfg.srs_period.has_value() or not cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()) { diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h index 4866ea0831..652b670bde 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h @@ -40,10 +40,10 @@ class du_srs_resource_manager /// objective to minimize the number of slots and symbols that contain the SRS resources, to reduce as much as possible /// the slots and symbols resources taken from the PUSCH. The drawback of this policy is that it can increase the /// inter-slot SRS interference among different UEs. -class du_srs_policy_max_ul_th : public du_srs_resource_manager +class du_srs_policy_max_ul_rate : public du_srs_resource_manager { public: - explicit du_srs_policy_max_ul_th(span cell_cfg_list_); + explicit du_srs_policy_max_ul_rate(span cell_cfg_list_); /// The SRS resources are allocate according to the following policy: /// - Give priority to resources that are placed on partially-UL slots, first. diff --git a/tests/unittests/du_manager/CMakeLists.txt b/tests/unittests/du_manager/CMakeLists.txt index 3ed401eb4f..d574499ae3 100644 --- a/tests/unittests/du_manager/CMakeLists.txt +++ b/tests/unittests/du_manager/CMakeLists.txt @@ -77,4 +77,9 @@ gtest_discover_tests(pucch_resource_generator_test) add_executable(srs_resource_generator_test srs_resource_generator_test.cpp) target_include_directories(srs_resource_generator_test PRIVATE ${CMAKE_SOURCE_DIR}) target_link_libraries(srs_resource_generator_test du_manager_test_helpers gtest gtest_main) -gtest_discover_tests(srs_resource_generator_test) \ No newline at end of file +gtest_discover_tests(srs_resource_generator_test) + +add_executable(du_srs_resource_manager_test du_srs_resource_manager_test.cpp) +target_include_directories(du_srs_resource_manager_test PRIVATE ${CMAKE_SOURCE_DIR}) +target_link_libraries(du_srs_resource_manager_test du_manager_test_helpers gtest gtest_main) +gtest_discover_tests(du_srs_resource_manager_test) \ No newline at end of file diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index f2ded3c76d..cdd0124b38 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -1058,7 +1058,7 @@ class du_srs_resource_manager_tester : public ::testing::TestWithParam cell_cfg_list; // This is a reference to the first element of cell_cfg_list's SRS config. const srs_builder_params& srs_params; - du_srs_policy_max_ul_th du_srs_res_mng; + du_srs_policy_max_ul_rate du_srs_res_mng; slotted_array ues; }; diff --git a/tests/unittests/du_manager/du_srs_resource_manager_test.cpp b/tests/unittests/du_manager/du_srs_resource_manager_test.cpp new file mode 100644 index 0000000000..2d3dc78229 --- /dev/null +++ b/tests/unittests/du_manager/du_srs_resource_manager_test.cpp @@ -0,0 +1,614 @@ +/* + * + * Copyright 2021-2024 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.h" +#include "srsran/du/du_cell_config_helpers.h" +#include "srsran/support/test_utils.h" +#include "fmt/ostream.h" +#include + +using namespace srsran; +using namespace srs_du; + +namespace { + +struct srs_params { + // If set, it's a TDD cell and the parameters indicates the number of UL symbols in the flexible slot. + std::optional nof_ul_symbols_p1; + bool test_optimality = false; +}; + +std::ostream& operator<<(std::ostream& out, const srs_params& params) +{ + if (params.nof_ul_symbols_p1.has_value()) { + out << fmt::format("TDD_nof_ul_symbols_p1_{}_test_optimality_{}", + params.nof_ul_symbols_p1.value(), + params.test_optimality ? "true" : "false"); + } else { + out << fmt::format("FDD_test_optimality_{}", params.test_optimality ? "true" : "false"); + } + return out; +} + +} // namespace + +static cell_config_builder_params make_cell_cfg_params(const srs_params& params) +{ + const bool is_tdd = params.nof_ul_symbols_p1.has_value(); + cell_config_builder_params cell_params = {.dl_f_ref_arfcn = not is_tdd ? 365000U : 520002U}; + if (is_tdd) { + auto& tdd_cfg = cell_params.tdd_ul_dl_cfg_common.emplace(); + tdd_cfg.pattern1.dl_ul_tx_period_nof_slots = 10; + tdd_cfg.pattern1.nof_dl_slots = 7; + tdd_cfg.pattern1.nof_dl_symbols = 2; + tdd_cfg.pattern1.nof_ul_slots = 2; + tdd_cfg.pattern1.nof_ul_symbols = params.nof_ul_symbols_p1.value(); + tdd_cfg.ref_scs = subcarrier_spacing::kHz30; + } + + return cell_params; +} + +static du_cell_config make_srs_base_du_cell_config(const cell_config_builder_params& params) +{ + // This function generates a configuration which would potentially allow for a very large number of SRS resources. + du_cell_config du_cfg = config_helpers::make_default_du_cell_config(params); + auto& srs_cfg = du_cfg.srs_cfg; + + // Generates a random SRS configuration. + srs_cfg.tx_comb = test_rgen::bernoulli(0.5) ? tx_comb_size::n2 : tx_comb_size::n4; + srs_cfg.max_nof_symbols = test_rgen::uniform_int(1U, 6U); + std::array nof_symb_values = {srs_nof_symbols::n1, srs_nof_symbols::n2, srs_nof_symbols::n4}; + srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; + while (srs_cfg.nof_symbols > srs_cfg.max_nof_symbols) { + srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; + } + + // The TX comb cyclic shift value depends on the TX comb size. + if (srs_cfg.tx_comb == srsran::tx_comb_size::n2) { + std::array srs_cyclic_shift_values = { + nof_cyclic_shifts::no_cyclic_shift, nof_cyclic_shifts::two, nof_cyclic_shifts::four}; + srs_cfg.cyclic_shift_reuse_factor = + srs_cyclic_shift_values[test_rgen::uniform_int(0, srs_cyclic_shift_values.size() - 1)]; + } else { + std::array srs_cyclic_shift_values = {nof_cyclic_shifts::no_cyclic_shift, + nof_cyclic_shifts::two, + nof_cyclic_shifts::three, + nof_cyclic_shifts::four, + nof_cyclic_shifts::six, + nof_cyclic_shifts::twelve}; + srs_cfg.cyclic_shift_reuse_factor = + srs_cyclic_shift_values[test_rgen::uniform_int(0, srs_cyclic_shift_values.size() - 1)]; + } + // [Implementation-defined] These are the values in the gNB, \ref sequence_id_reuse_factor. + std::array srs_seq_id_values = {1, 2, 3, 5, 6, 10, 15, 30}; + srs_cfg.sequence_id_reuse_factor = + srs_seq_id_values[test_rgen::uniform_int(0, srs_seq_id_values.size() - 1)]; + + if (du_cfg.tdd_ul_dl_cfg_common.has_value()) { + std::array period_values = {srs_periodicity::sl10, + srs_periodicity::sl20, + srs_periodicity::sl40, + srs_periodicity::sl80, + srs_periodicity::sl160, + srs_periodicity::sl320, + srs_periodicity::sl640, + srs_periodicity::sl1280}; + srs_cfg.srs_period.emplace(period_values[test_rgen::uniform_int(0, period_values.size() - 1)]); + } else { + std::array period_values = {srs_periodicity::sl1, + srs_periodicity::sl2, + srs_periodicity::sl4, + srs_periodicity::sl5, + srs_periodicity::sl8, + srs_periodicity::sl10, + srs_periodicity::sl16, + srs_periodicity::sl20, + srs_periodicity::sl32, + srs_periodicity::sl40}; + srs_cfg.srs_period.emplace(period_values[test_rgen::uniform_int(0, period_values.size() - 1)]); + } + + return du_cfg; +} + +static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& params, bool limit_srs_res) +{ + auto du_cfg = make_srs_base_du_cell_config(params); + + // For the optimality test, we to have a configuration that doesn't allow for more than 1024 SRS resources. + if (not limit_srs_res) { + return du_cfg; + } + + // This function calculates the total number of SRS resources that can be potentially allocated in the cell with the + // given SRS parameters. + auto tot_num_srs_res = [&du_cfg]() { + auto& tdd_cfg = du_cfg.tdd_ul_dl_cfg_common; + auto& srs_cfg = du_cfg.srs_cfg; + // This is the number of SRS resources per symbol interval. A symbol interval is an interval where the SRS resource + // can be placed within a slot and its width (or length) is given by the corresponding SRS parameter \c nof_symb in + // the SRS configuration. + const unsigned nof_res_per_symb_interval = srs_cfg.sequence_id_reuse_factor * + static_cast(srs_cfg.cyclic_shift_reuse_factor) * + static_cast(srs_cfg.tx_comb); + + // This "number of symbols intervals" counts all the symbols intervals within the SRS period. + unsigned nof_symb_intervals = 0; + + // The number of symbols interval per slot depends on whether it's FDD or TDD. + if (not tdd_cfg.has_value()) { + // In FDD, in an SRS period we can "max_nof_symbols / nof_symbols" intervals per slot. + nof_symb_intervals = srs_cfg.max_nof_symbols.to_uint() / static_cast(srs_cfg.nof_symbols) * + static_cast(srs_cfg.srs_period.value()); + } else { + // In TDD, in an SRS period we can "max_nof_symbols / nof_symbols" intervals per UL slot; in addition to this, the + // partially-UL slots can have extra symbols intervals, up to a maximum of 6U, which is the max number of symbols + // usable for SRS resources. + nof_symb_intervals = + (srs_cfg.max_nof_symbols.to_uint() / static_cast(srs_cfg.nof_symbols)) * + tdd_cfg->pattern1.nof_ul_slots * + (static_cast(srs_cfg.srs_period.value()) / tdd_cfg->pattern1.dl_ul_tx_period_nof_slots); + if (tdd_cfg->pattern1.nof_ul_symbols != 0) { + nof_symb_intervals += + (std::min(tdd_cfg->pattern1.nof_ul_symbols, srs_cfg.max_nof_symbols.max()) / + static_cast(srs_cfg.nof_symbols)) * + (static_cast(srs_cfg.srs_period.value()) / tdd_cfg->pattern1.dl_ul_tx_period_nof_slots); + } + } + + // Return the total number of SRS resources. + return nof_symb_intervals * nof_res_per_symb_interval; + }; + + while (tot_num_srs_res() > static_cast(MAX_NOF_DU_UES)) { + du_cfg = make_srs_base_du_cell_config(params); + } + + return du_cfg; +} + +class du_srs_resource_manager_tester : public ::testing::TestWithParam +{ +protected: + explicit du_srs_resource_manager_tester(cell_config_builder_params params_ = make_cell_cfg_params(GetParam())) : + params(params_), + cell_cfg_list({make_srs_du_cell_config(params_, GetParam().test_optimality)}), + srs_params(cell_cfg_list[0].srs_cfg), + du_srs_res_mng(cell_cfg_list) + { + } + + std::optional add_ue(du_ue_index_t ue_idx) + { + if (ue_idx >= MAX_NOF_DU_UES) { + return std::nullopt; + } + + cell_group_config cell_grp_cfg; + std::unique_ptr cell_grp_cfg_ptr = std::make_unique(); + cell_grp_cfg.cells.insert( + serv_cell_index_t::SERVING_CELL_PCELL_IDX, + cell_config_dedicated{serv_cell_index_t::SERVING_CELL_PCELL_IDX, + config_helpers::create_default_initial_ue_serving_cell_config(params)}); + ues.insert(ue_idx, cell_grp_cfg); + auto& ue = ues[ue_idx]; + + // Reset the SRS config before allocating resources. + ue.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); + + bool res = du_srs_res_mng.alloc_resources(ue); + if (res) { + return ue; + } + // If the allocation was not possible, remove the UE. + ues.erase(ue_idx); + return std::nullopt; + } + + // Helper struct that keeps track of the SRS resource parameter assigned to the UEs. + struct srs_res_params { + unsigned offset; + unsigned tx_comb_offset; + ofdm_symbol_range symbols; + unsigned sequence_id; + unsigned cs; + + // Constructor for the srs_res_params struct given srs_resource. + explicit srs_res_params(const srs_config::srs_resource& srs_res) : + offset(srs_res.periodicity_and_offset->offset), + tx_comb_offset(srs_res.tx_comb.tx_comb_offset), + symbols(ofdm_symbol_range{NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res.res_mapping.start_pos - 1, + NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res.res_mapping.start_pos - 1 + + srs_res.res_mapping.nof_symb}), + sequence_id(srs_res.sequence_id), + cs(srs_res.tx_comb.tx_comb_cyclic_shift) + { + } + + // Returns true is SRS resource collides with another SRS resource; it is used to check if the SRS resources are + // orthogonal. + bool collides(const srs_res_params& rhs) const + { + return offset == rhs.offset and tx_comb_offset == rhs.tx_comb_offset and symbols.overlaps(rhs.symbols) and + sequence_id == rhs.sequence_id and cs == rhs.cs; + } + + bool operator==(const srs_res_params& rhs) const + { + return offset == rhs.offset and tx_comb_offset == rhs.tx_comb_offset and symbols == rhs.symbols and + sequence_id == rhs.sequence_id and cs == rhs.cs; + } + + bool operator!=(const srs_res_params& rhs) const { return not operator==(rhs); } + }; + + // Helper that computes the C_SRS parameter (see Section 6.4.1.4.3, TS 38.211). + unsigned compute_c_srs() const + { + // In this test, we only consider the case where B_SRS is 0. + const uint8_t b_srs = 0U; + unsigned candidate_c_srs = 0U; + unsigned candidate_m_srs = 0U; + // Spans over Table 6.4.1.4.3-1 in TS 38.211 and find the smallest C_SRS that maximizes m_srs_0 under the + // constraint of m_SRS <= nof_BW_RBs. + for (unsigned c_srs_it = 0; c_srs_it != 64; ++c_srs_it) { + std::optional srs_cfg = srs_configuration_get(c_srs_it, b_srs); + srsran_assert(srs_cfg.has_value(), "C_SRS is required for this unittest"); + if (srs_cfg.value().m_srs <= cell_cfg_list[0].ul_cfg_common.init_ul_bwp.generic_params.crbs.length() and + srs_cfg.value().m_srs > candidate_m_srs) { + candidate_m_srs = srs_cfg->m_srs; + candidate_c_srs = c_srs_it; + } + } + return candidate_c_srs; + } + + // Helper that computes the Frequency Shift parameter (see Section 6.4.1.4.3, TS 38.211). + unsigned compute_freq_shift() const + { + // The function computes the frequency shift so that the SRS resources are placed in the center of the band. + unsigned c_srs = compute_c_srs(); + unsigned ul_bw_nof_rbs = cell_cfg_list[0].ul_cfg_common.init_ul_bwp.generic_params.crbs.length(); + const auto srs_cfg = srs_configuration_get(c_srs, 0U); + srsran_assert(srs_cfg.has_value(), "C_SRS is required for this unittest"); + return (ul_bw_nof_rbs - srs_cfg.value().m_srs) / 2U; + } + + cell_config_builder_params params; + std::vector cell_cfg_list; + // This is a reference to the first element of cell_cfg_list's SRS config. + const srs_builder_params& srs_params; + du_srs_policy_max_ul_rate du_srs_res_mng; + slotted_array ues; +}; + +static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0; +} + +static bool is_partially_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + const unsigned nof_symbols = srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); + return nof_symbols != 0 and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; +} + +TEST_P(du_srs_resource_manager_tester, ue_are_assigned_orthogonal_srs_resources) +{ + du_ue_index_t next_ue_index = to_du_ue_index(0); + + // Keeps track of which SRS resources have been assigned to the UEs. + std::vector used_srs_resources; + // > Created UEs have unique SRS resources. + for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { + std::optional ue = add_ue(to_du_ue_index(i)); + if (not ue.has_value()) { + break; + } + + // Check if the SRS has been assigned to the UE. + const auto& srs_res_list = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list; + ASSERT_FALSE(srs_res_list.empty()); + // Check if the SRS resource collides (i.e., is not orthogonal) with any other SRS resource. + const auto& srs_res = srs_res_list[0]; + const srs_res_params res_params(srs_res); + ASSERT_FALSE(std::any_of(used_srs_resources.begin(), + used_srs_resources.end(), + [&res_params](const srs_res_params& res) { return res.collides(res_params); })); + + used_srs_resources.push_back(res_params); + next_ue_index = to_du_ue_index((unsigned)next_ue_index + 1); + } + + // Erase a random UE and attempt. + const du_ue_index_t ue_idx_to_rem = to_du_ue_index(test_rgen::uniform_int(0, ues.size() - 1)); + du_srs_res_mng.dealloc_resources(ues[ue_idx_to_rem]); + auto& ue_to_be_removed = ues[ue_idx_to_rem]; + // First, find the SRS resource of the ue to be removed and removed it from the vector of used resources. + srs_res_params srs_res_to_be_removed( + ue_to_be_removed.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list[0]); + auto res_to_remove_it = std::find(used_srs_resources.begin(), used_srs_resources.end(), srs_res_to_be_removed); + ASSERT_FALSE(res_to_remove_it == used_srs_resources.end()); + used_srs_resources.erase(res_to_remove_it); + ues.erase(ue_idx_to_rem); + + // Attempt a new allocation and verify it is successful. + next_ue_index = to_du_ue_index((unsigned)next_ue_index + 1); + std::optional ue = add_ue(ue_idx_to_rem); + ASSERT_TRUE(ue.has_value()); + + // Check if the SRS has been assigned to the UE. + const auto& srs_res_list = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list; + ASSERT_FALSE(srs_res_list.empty()); + // Check if the SRS resource collides (i.e., is not orthogonal) with any other SRS resource. + const auto& srs_res = srs_res_list[0]; + const srs_res_params res_params(srs_res); + ASSERT_FALSE(std::any_of(used_srs_resources.begin(), + used_srs_resources.end(), + [&res_params](const srs_res_params& res) { return res.collides(res_params); })); +} + +TEST_P(du_srs_resource_manager_tester, srs_resources_parameters_are_valid) +{ + // > Created UEs have unique SRS resources. + for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { + std::optional ue = add_ue(to_du_ue_index(i)); + if (not ue.has_value()) { + break; + } + + // Verify all parameters of the SRS resource are as expected. + ASSERT_TRUE(ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); + const auto& ue_srs_config = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + // Verify first the SRS resource set list. + ASSERT_EQ(ue_srs_config.srs_res_set_list.size(), 1U); + ASSERT_EQ(ue_srs_config.srs_res_set_list[0].id, 0U); + ASSERT_TRUE(std::holds_alternative( + ue_srs_config.srs_res_set_list[0].res_type)); + ASSERT_EQ(ue_srs_config.srs_res_set_list[0].srs_res_id_list.size(), 1U); + ASSERT_EQ(ue_srs_config.srs_res_set_list[0].srs_res_id_list[0], 0U); + ASSERT_EQ(ue_srs_config.srs_res_list.size(), 1U); + const auto& srs_res = ue_srs_config.srs_res_list[0]; + ASSERT_EQ(srs_res.id.ue_res_id, static_cast(0U)); + ASSERT_TRUE(srs_res.periodicity_and_offset.has_value()); + ASSERT_EQ(srs_res.periodicity_and_offset->period, srs_params.srs_period.value()); + ASSERT_LT(srs_res.periodicity_and_offset->offset, static_cast(srs_res.periodicity_and_offset->period)); + if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value()) { + ASSERT_TRUE(is_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())); + } + ASSERT_LT(srs_res.tx_comb.tx_comb_offset, static_cast(srs_res.tx_comb.size)); + ASSERT_LT(srs_res.tx_comb.tx_comb_cyclic_shift, srs_res.tx_comb.size == tx_comb_size::n2 ? 8U : 12U); + + ASSERT_EQ(srs_res.freq_hop.c_srs, compute_c_srs()); + ASSERT_EQ(srs_res.freq_hop.b_srs, 0U); + ASSERT_EQ(srs_res.freq_hop.b_hop, 0U); + ASSERT_EQ(srs_res.freq_domain_shift, compute_freq_shift()); + ASSERT_EQ(srs_res.freq_domain_pos, 0U); + + // Verify the symbols, depending on whether it's FDD, or TDD. + ASSERT_EQ(srs_res.res_mapping.nof_symb, srs_params.nof_symbols); + if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value() and + is_partially_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { + ASSERT_LT(srs_res.res_mapping.start_pos, cell_cfg_list[0].tdd_ul_dl_cfg_common.value().pattern1.nof_ul_symbols); + } else { + ASSERT_LT(srs_res.res_mapping.start_pos, srs_params.max_nof_symbols.to_uint()); + } + } +} + +INSTANTIATE_TEST_SUITE_P(test_du_srs_res_mng_for_different_ul_symbols, + du_srs_resource_manager_tester, + ::testing::Values(srs_params{.nof_ul_symbols_p1 = std::nullopt}, + srs_params{.nof_ul_symbols_p1 = 0U}, + srs_params{.nof_ul_symbols_p1 = 1U}, + srs_params{.nof_ul_symbols_p1 = 2U}, + srs_params{.nof_ul_symbols_p1 = 3U}, + srs_params{.nof_ul_symbols_p1 = 4U}, + srs_params{.nof_ul_symbols_p1 = 5U}, + srs_params{.nof_ul_symbols_p1 = 6U}, + srs_params{.nof_ul_symbols_p1 = 7U}), + [](const testing::TestParamInfo& params_item) { + return fmt::format("{}", params_item.param); + }); + +///////// Test the optimality of DU SRS resource manager policy ///////// + +class du_srs_resource_manager_tester_optimality : public du_srs_resource_manager_tester +{ +protected: + explicit du_srs_resource_manager_tester_optimality() + { + nof_srs_res_per_symb_interval = static_cast(srs_params.tx_comb) * + static_cast(srs_params.cyclic_shift_reuse_factor) * + static_cast(srs_params.sequence_id_reuse_factor); + srs_res_tracker.reserve(static_cast(srs_params.srs_period.value())); + + // Build the SRS resource tracker. + for (unsigned offset = 0; offset != static_cast(srs_params.srs_period.value()); ++offset) { + if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value()) { + const auto& tdd_cfg = cell_cfg_list[0].tdd_ul_dl_cfg_common.value(); + + if (not is_ul_slot(offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { + // In TDD, no SRS resources can be allocated in DL slots. + srs_res_tracker.emplace_back(0U); + } else if (is_partially_ul_slot(offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + const unsigned nof_ul_symbols = + srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); + // The number of symbols intervals is limited by the number of symbols where the SRS can be placed. + const unsigned nof_intervals = std::min(nof_ul_symbols / static_cast(srs_params.nof_symbols), + srs_params.max_nof_symbols.max()); + srs_res_tracker.emplace_back(nof_intervals); + } else { + const unsigned nof_intervals = + srs_params.max_nof_symbols.to_uint() / static_cast(srs_params.nof_symbols); + srs_res_tracker.emplace_back(nof_intervals); + } + } + // FDD case. + else { + const unsigned nof_intervals = + srs_params.max_nof_symbols.to_uint() / static_cast(srs_params.nof_symbols); + srs_res_tracker.emplace_back(nof_intervals); + } + } + } + + // Helper struct that keeps track of the number of SRS resources per symbol interval for a given offset. + struct res_per_slot_tracker { + explicit res_per_slot_tracker(unsigned nof_srs_symb_intervals_per_slot_) : + nof_srs_symb_intervals_per_slot(nof_srs_symb_intervals_per_slot_) + { + // Initialize the vector with zeros, as at the beginning no SRS resources have been allocated. + res_per_symb_interval.assign(nof_srs_symb_intervals_per_slot, 0U); + } + + const unsigned nof_srs_symb_intervals_per_slot; + // This vector keeps track of the number of SRS resources per symbol interval. The symbol interval with index 0 is + // the last one in the slot; the symbol interval with index 1 is the second to last, and so on. + std::vector res_per_symb_interval; + }; + + // The number of SRS resources per symbol interval, which depends on the TX comb size, on the cyclic shift reuse + // factor, and on the sequence ID reuse factor. + unsigned nof_srs_res_per_symb_interval = 0; + // This vector keeps track of the number of SRS resources per symbol interval for each offset. + std::vector srs_res_tracker; + + // Save the SRS resource allocation in the tracker. + void track_srs_res_alloc(const srs_config::srs_resource& srs_res) + { + srsran_assert(srs_res.periodicity_and_offset.has_value(), "SRS resource must have a periodicity and offset"); + const unsigned srs_offset = srs_res.periodicity_and_offset->offset; + const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); + srsran_assert(interval_idx < srs_res_tracker[srs_offset].res_per_symb_interval.size(), + "SRS resource must have a periodicity and offset"); + ++srs_res_tracker[srs_offset].res_per_symb_interval[interval_idx]; + } + + // Check if there is any partially-UL slot that has not completely filled with SRS resources. + bool has_free_partial_ul_slots() + { + for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { + if (not is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value())) { + continue; + } + if (std::any_of(srs_res_tracker[n].res_per_symb_interval.begin(), + srs_res_tracker[n].res_per_symb_interval.end(), + [this](unsigned cnt) { return cnt < nof_srs_res_per_symb_interval; })) { + return true; + } + } + return false; + } + + // Check if all the symbol intervals with index lower than the one of the given SRS resource have + // been used (in fully-UL slots). + bool all_lower_intervals_used(const srs_config::srs_resource& srs_res) + { + const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); + if (interval_idx == 0) { + return true; + } + + for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { + if (params.tdd_ul_dl_cfg_common.has_value() and (not is_ul_slot(n, params.tdd_ul_dl_cfg_common.value()) or + is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value()))) { + continue; + } + if (std::any_of(srs_res_tracker[n].res_per_symb_interval.begin(), + srs_res_tracker[n].res_per_symb_interval.begin() + interval_idx, + [this](unsigned cnt) { return cnt < nof_srs_res_per_symb_interval; })) { + return false; + } + } + return true; + } + + // Check if there is any symbol interval of the same index of the one of the given SRS resource that is not empty, but + // not full either. + bool non_empty_non_full_interval(const srs_config::srs_resource& srs_res) + { + const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); + for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { + // Skip the slot where the SRS resource has been allocated, otherwise this will always return true. + if (n == srs_res.periodicity_and_offset->offset) { + continue; + } + if (params.tdd_ul_dl_cfg_common.has_value() and (not is_ul_slot(n, params.tdd_ul_dl_cfg_common.value()) or + is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value()))) { + continue; + } + srsran_assert(interval_idx < srs_res_tracker[n].res_per_symb_interval.size(), + "Interval index exceeds the size of the vector"); + if (srs_res_tracker[n].res_per_symb_interval[interval_idx] > 0U and + srs_res_tracker[n].res_per_symb_interval[interval_idx] < nof_srs_res_per_symb_interval) { + return true; + } + } + return false; + } +}; + +TEST_P(du_srs_resource_manager_tester_optimality, srs_are_assigned_according_to_class_policy) +{ + // > Created UEs have unique SRS resources. + for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { + std::optional ue = add_ue(to_du_ue_index(i)); + if (not ue.has_value()) { + break; + } + + // Verify all parameters of the SRS resource are as expected. + ASSERT_TRUE(ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); + const auto& ue_srs_config = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + const auto& srs_res = ue_srs_config.srs_res_list[0]; + + // Save the SRS resource allocation in the tracker. + track_srs_res_alloc(srs_res); + + // The SRS allocation assigns resources according to the policy: + // - If there is a partially-UL slot available, then the SRS resources are allocated in the partially-UL slots. + // - If there are no partially-UL slots, then the SRS resources are allocated in the fully-UL slots. + // - If there are no fully-UL slots with a symbol interval of index i available, then the SRS resources are + // allocated in a symbol interval of index i+1, in any slot. + // - If there is a fully-UL slots with a symbol interval of index i available that has already SRS resources + // allocated, but has not been completely filled, then the SRS resources are allocated in that slot. + if (params.tdd_ul_dl_cfg_common.has_value()) { + if (not is_partially_ul_slot(srs_res.periodicity_and_offset.value().offset, + params.tdd_ul_dl_cfg_common.value())) { + ASSERT_FALSE(has_free_partial_ul_slots()); + ASSERT_TRUE(all_lower_intervals_used(srs_res)); + ASSERT_FALSE(non_empty_non_full_interval(srs_res)); + } + } else { + ASSERT_TRUE(all_lower_intervals_used(srs_res)); + ASSERT_FALSE(non_empty_non_full_interval(srs_res)); + } + } +} + +INSTANTIATE_TEST_SUITE_P(test_du_srs_res_mng_for_different_ul_symbols, + du_srs_resource_manager_tester_optimality, + ::testing::Values(srs_params{.nof_ul_symbols_p1 = std::nullopt, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 0U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 1U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 2U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 3U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 4U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 5U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 6U, .test_optimality = true}, + srs_params{.nof_ul_symbols_p1 = 7U, .test_optimality = true}), + [](const testing::TestParamInfo& params_item) { + return fmt::format("{}", params_item.param); + }); From ab854aa626f817f9d4a27857fee874f972719736 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 27 Sep 2024 16:50:24 +0200 Subject: [PATCH 174/174] du: some simplification in the DU SRS res mng Signed-off-by: Carlo Galiotto --- include/srsran/ran/tdd/tdd_ul_dl_config.h | 3 + .../du_srs_resource_manager.cpp | 137 ++-- lib/ran/tdd_ul_dl_config.cpp | 6 + .../config/serving_cell_config_factory.cpp | 3 +- .../du_ran_resource_manager_test.cpp | 598 ------------------ .../du_srs_resource_manager_test.cpp | 25 +- 6 files changed, 91 insertions(+), 681 deletions(-) diff --git a/include/srsran/ran/tdd/tdd_ul_dl_config.h b/include/srsran/ran/tdd/tdd_ul_dl_config.h index 6f9c541647..c5a99ab020 100644 --- a/include/srsran/ran/tdd/tdd_ul_dl_config.h +++ b/include/srsran/ran/tdd/tdd_ul_dl_config.h @@ -71,6 +71,9 @@ bool is_tdd_full_dl_slot(const tdd_ul_dl_config_common& cfg, unsigned slot_index /// \brief Checks if all symbols in the current slot index are active for UL. bool is_tdd_full_ul_slot(const tdd_ul_dl_config_common& cfg, unsigned slot_index); +/// \brief Checks if some symbols in the current slot index, but not all of them, are active for UL. +bool is_tdd_partial_ul_slot(const tdd_ul_dl_config_common& cfg, unsigned slot_index); + /// \brief Calculates the number of active DL symbols in the current slot_index. ofdm_symbol_range get_active_tdd_dl_symbols(const tdd_ul_dl_config_common& cfg, unsigned slot_index, cyclic_prefix cp); diff --git a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp index 6d8750b031..edc26ca8b6 100644 --- a/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp +++ b/lib/du/du_high/du_manager/ran_resource_management/du_srs_resource_manager.cpp @@ -59,8 +59,8 @@ static unsigned compute_freq_shift(unsigned c_srs, unsigned nof_ul_rbs) { // As per Section 6.4.1.4.3, the parameter \f$m_{SRS}\f$ = 0 is an index that, along with \f$C_{SRS}\f$, maps to the // bandwidth of the SRS resources. - constexpr uint8_t b_srs_0 = 0; - std::optional srs_params = srs_configuration_get(c_srs, b_srs_0); + constexpr uint8_t b_srs_0 = 0; + std::optional srs_params = srs_configuration_get(c_srs, b_srs_0); srsran_sanity_check(srs_params.has_value() and nof_ul_rbs >= srs_params.value().m_srs, "The SRS configuration is not valid"); @@ -70,14 +70,13 @@ static unsigned compute_freq_shift(unsigned c_srs, unsigned nof_ul_rbs) static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) { const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0; + return has_active_tdd_ul_symbols(tdd_cfg, slot_index); } -static bool is_partually_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +static bool is_partially_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) { - const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - const unsigned nof_symbols = srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); - return nof_symbols != 0 and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + return is_tdd_partial_ul_slot(tdd_cfg, slot_index); } // Helper that updates the starting SRS config with user-defined parameters. @@ -120,6 +119,8 @@ du_srs_policy_max_ul_rate::cell_context::cell_context(const du_cell_config& cfg) du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span cell_cfg_list_) : cells(cell_cfg_list_.begin(), cell_cfg_list_.end()) { + static constexpr unsigned primary_cell_index = 0U; + for (auto& cell : cells) { if (not cell.cell_cfg.srs_cfg.srs_period.has_value()) { continue; @@ -139,6 +140,7 @@ du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span const auto srs_period_slots = static_cast(cell.cell_cfg.srs_cfg.srs_period.value()); // Reserve the size of the vector and set the SRS counter of each offset to 0. + cell.slot_resource_cnt.reserve(srs_period_slots); cell.slot_resource_cnt.assign(srs_period_slots, 0U); cell.srs_res_offset_free_list.reserve(du_srs_policy_max_ul_rate::cell_context::max_nof_srs_res); cell.nof_res_per_symb_interval = static_cast(cell.cell_cfg.srs_cfg.tx_comb) * @@ -152,42 +154,33 @@ du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span } // Verify whether the offset maps to a partially- or fully-UL slot. - if (cell_cfg_list_[0].tdd_ul_dl_cfg_common.has_value() and - not is_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { + if (cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common.has_value() and + not is_ul_slot(offset, cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common.value())) { continue; } for (auto& res : cell.cell_srs_res_list) { // Handle TDD and FDD configurations separately, as we treat partially-UL slots differently from // fully-UL slots. - if (cell_cfg_list_[0].tdd_ul_dl_cfg_common.has_value()) { - const auto& tdd_cfg = cell_cfg_list_[0].tdd_ul_dl_cfg_common.value(); - // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the + if (cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common.has_value() and + is_partially_ul_slot(offset, cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common.value())) { + // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the slot. + const auto& tdd_cfg = cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common.value(); + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + // As per Section 6.4.1.4.1, TS 38.211, the SRS resources can only be placed in the last 6 symbols of the // slot. - if (is_partually_ul_slot(offset, cell_cfg_list_[0].tdd_ul_dl_cfg_common.value())) { - const unsigned slot_index = - offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - // As per Section 6.4.1.4.1, TS 38.211, the SRS resources can only be placed in the last 6 symbols of the - // slot. - static constexpr unsigned max_srs_symbols = 6U; - const unsigned nof_ul_symbols_for_srs = - std::min(srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(), - max_srs_symbols); - if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - nof_ul_symbols_for_srs) { - continue; - } - } - // This is the fully-UL slot case: check if the SRS can be placed in the UL symbols of the slot. - else if (res.symbols.start() < - NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell.cell_cfg.srs_cfg.max_nof_symbols.to_uint()) { + static constexpr unsigned max_srs_symbols = 6U; + const unsigned nof_ul_symbols_for_srs = + std::min(get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(), max_srs_symbols); + if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - nof_ul_symbols_for_srs) { continue; } } - // FDD case. - else { - if (res.symbols.start() < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell.cell_cfg.srs_cfg.max_nof_symbols.to_uint()) { - continue; - } + // NOTE: for TDD, the offset that are not UL slots are skipped above. + // FDD case and TDD case for fully-UL slot. + else if (res.symbols.start() < + NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell.cell_cfg.srs_cfg.max_nof_symbols.to_uint()) { + continue; } cell.srs_res_offset_free_list.emplace_back(res.cell_res_id, offset); } @@ -197,48 +190,50 @@ du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg) { + static constexpr unsigned primary_cell_index = 0U; + // TODO: Adapt this to the case of UEs with multiple cells configs. - srsran_assert( - cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value() and - not cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value(), - "UE UL config should be non-empty but with an empty SRS config"); + srsran_assert(cells[cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.cell_index] + .cell_cfg.ue_ded_serv_cell_cfg.ul_config.has_value() and + not cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value(), + "UE UL config should be non-empty but with an empty SRS config"); - cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( - cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].default_srs_cfg); + cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( + cells[cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.cell_index].default_srs_cfg); // If periodic SRS is not enabled, don't allocate anything and exit with success. - if (not cells[0].cell_cfg.srs_cfg.srs_period.has_value()) { + if (not cells[primary_cell_index].cell_cfg.srs_cfg.srs_period.has_value()) { return true; } // The UE SRS configuration is taken from a base configuration, saved in the GNB. The UE specific parameters will be // added later on in this function. - cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( - cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].default_srs_cfg); - srs_config& ue_srs_cfg = cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); - auto& free_srs_list = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_res_offset_free_list; + cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.emplace( + cells[cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.cell_index].default_srs_cfg); + srs_config& ue_srs_cfg = cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + auto& free_srs_list = cells[cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.cell_index].srs_res_offset_free_list; // Verify where there are SRS resources to allocate a new UE. if (free_srs_list.empty()) { // If the allocation failed, reset the SRS configuration. - cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); + cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); return false; } // Find the best resource ID and offset for this UE, according to the class policy. - auto srs_res_id_offset = cells[0].find_optimal_ue_srs_resource(); + auto srs_res_id_offset = cells[primary_cell_index].find_optimal_ue_srs_resource(); if (srs_res_id_offset == free_srs_list.end()) { // If the allocation failed, reset the SRS configuration. - cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); + cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); return false; } - const auto& du_res_it = cells[0].get_du_srs_res_cfg(srs_res_id_offset->first); + const auto& du_res_it = cells[primary_cell_index].get_du_srs_res_cfg(srs_res_id_offset->first); - if (du_res_it == cells[0].cell_srs_res_list.end()) { + if (du_res_it == cells[primary_cell_index].cell_srs_res_list.end()) { // If the allocation failed, reset the SRS configuration. - cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); + cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); return false; } @@ -250,12 +245,13 @@ bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg) // NOTE: given that there is only 1 SRS resource per UE, we can assume that the SRS resource ID is 0. only_ue_srs_res.id.cell_res_id = du_res.cell_res_id; only_ue_srs_res.id.ue_res_id = static_cast(0U); - srsran_assert(cells[0].cell_cfg.ul_carrier.nof_ant == 1 or cells[0].cell_cfg.ul_carrier.nof_ant == 2 or - cells[0].cell_cfg.ul_carrier.nof_ant == 4, + srsran_assert(cells[primary_cell_index].cell_cfg.ul_carrier.nof_ant == 1 or + cells[primary_cell_index].cell_cfg.ul_carrier.nof_ant == 2 or + cells[primary_cell_index].cell_cfg.ul_carrier.nof_ant == 4, "The number of UL antenna ports is not valid"); only_ue_srs_res.nof_ports = - static_cast(cells[0].cell_cfg.ul_carrier.nof_ant); - only_ue_srs_res.tx_comb.size = cells[0].cell_cfg.srs_cfg.tx_comb; + static_cast(cells[primary_cell_index].cell_cfg.ul_carrier.nof_ant); + only_ue_srs_res.tx_comb.size = cells[primary_cell_index].cell_cfg.srs_cfg.tx_comb; only_ue_srs_res.tx_comb.tx_comb_offset = du_res.tx_comb_offset.to_uint(); only_ue_srs_res.tx_comb.tx_comb_cyclic_shift = du_res.cs; only_ue_srs_res.freq_domain_pos = du_res.freq_dom_position; @@ -264,16 +260,18 @@ bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg) only_ue_srs_res.sequence_id = du_res.sequence_id; // Update the SRS configuration with the parameters that are common to the cell. - only_ue_srs_res.freq_hop.c_srs = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.c_srs; + only_ue_srs_res.freq_hop.c_srs = + cells[cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.cell_index].srs_common_params.c_srs; // We assume that the frequency hopping is disabled and that the SRS occupies all possible RBs within the BWP. Refer // to Section 6.4.1.4.3, TS 38.211. only_ue_srs_res.freq_hop.b_srs = 0U; only_ue_srs_res.freq_hop.b_hop = 0U; only_ue_srs_res.freq_domain_shift = - cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_common_params.freq_shift; + cells[cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.cell_index].srs_common_params.freq_shift; - only_ue_srs_res.periodicity_and_offset.emplace(srs_config::srs_periodicity_and_offset{ - .period = cells[0].cell_cfg.srs_cfg.srs_period.value(), .offset = static_cast(srs_offset)}); + only_ue_srs_res.periodicity_and_offset.emplace( + srs_config::srs_periodicity_and_offset{.period = cells[primary_cell_index].cell_cfg.srs_cfg.srs_period.value(), + .offset = static_cast(srs_offset)}); // Update the SRS resource set with the SRS id. ue_srs_cfg.srs_res_set_list.front().srs_res_id_list.front() = only_ue_srs_res.id.ue_res_id; @@ -282,12 +280,12 @@ bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg) free_srs_list.erase(srs_res_id_offset); // Update the SRS resource per slot counter. - ++cells[0].slot_resource_cnt[srs_offset]; + ++cells[primary_cell_index].slot_resource_cnt[srs_offset]; return true; } -std::vector>::const_iterator +std::vector::const_iterator du_srs_policy_max_ul_rate::cell_context::find_optimal_ue_srs_resource() { // The weights assigned here can be set to arbitrarily value, as long as: @@ -301,7 +299,7 @@ du_srs_policy_max_ul_rate::cell_context::find_optimal_ue_srs_resource() const auto weight_function = [&](const pair_res_id_offset& srs_res) { if (cell_cfg.tdd_ul_dl_cfg_common.has_value() and - is_partually_ul_slot(srs_res.second, cell_cfg.tdd_ul_dl_cfg_common.value())) { + is_partially_ul_slot(srs_res.second, cell_cfg.tdd_ul_dl_cfg_common.value())) { return 0U; } @@ -338,24 +336,27 @@ du_srs_policy_max_ul_rate::cell_context::find_optimal_ue_srs_resource() void du_srs_policy_max_ul_rate::dealloc_resources(cell_group_config& cell_grp_cfg) { - if (not cells[0].cell_cfg.srs_cfg.srs_period.has_value() or - not cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()) { + static constexpr unsigned primary_cell_index = 0U; + + if (not cells[primary_cell_index].cell_cfg.srs_cfg.srs_period.has_value() or + not cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()) { return; } - const auto& ue_srs_cfg = cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); - auto& free_srs_list = cells[cell_grp_cfg.cells[0].serv_cell_cfg.cell_index].srs_res_offset_free_list; + const auto& ue_srs_cfg = cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); + auto& free_srs_list = cells[cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.cell_index].srs_res_offset_free_list; for (const auto& srs_res : ue_srs_cfg.srs_res_list) { const unsigned offset_to_deallocate = srs_res.periodicity_and_offset.value().offset; free_srs_list.emplace_back(srs_res.id.cell_res_id, offset_to_deallocate); // Update the used_not_full slot vector. - srsran_assert(cells[0].slot_resource_cnt[offset_to_deallocate] != 0, "The offset is expected to be non-zero"); - --cells[0].slot_resource_cnt[offset_to_deallocate]; + srsran_assert(cells[primary_cell_index].slot_resource_cnt[offset_to_deallocate] != 0, + "The offset is expected to be non-zero"); + --cells[primary_cell_index].slot_resource_cnt[offset_to_deallocate]; } // Reset the SRS configuration in this UE. This makes sure the DU will exit this function immediately when it gets // called again for the same UE (upon destructor's call). - cell_grp_cfg.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); + cell_grp_cfg.cells[primary_cell_index].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); } diff --git a/lib/ran/tdd_ul_dl_config.cpp b/lib/ran/tdd_ul_dl_config.cpp index a2870ad7f2..5f9c8cd525 100644 --- a/lib/ran/tdd_ul_dl_config.cpp +++ b/lib/ran/tdd_ul_dl_config.cpp @@ -68,6 +68,12 @@ bool srsran::is_tdd_full_ul_slot(const tdd_ul_dl_config_common& cfg, unsigned sl return nof_active_symbols(cfg, slot_index, cyclic_prefix::NORMAL, false) == NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; } +bool srsran::is_tdd_partial_ul_slot(const tdd_ul_dl_config_common& cfg, unsigned slot_index) +{ + const unsigned nof_symbols = nof_active_symbols(cfg, slot_index, cyclic_prefix::NORMAL, false); + return nof_symbols != 0U and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; +} + ofdm_symbol_range srsran::get_active_tdd_dl_symbols(const tdd_ul_dl_config_common& cfg, unsigned slot_index, cyclic_prefix cp) { diff --git a/lib/scheduler/config/serving_cell_config_factory.cpp b/lib/scheduler/config/serving_cell_config_factory.cpp index a53f5dd348..3d19236ec2 100644 --- a/lib/scheduler/config/serving_cell_config_factory.cpp +++ b/lib/scheduler/config/serving_cell_config_factory.cpp @@ -498,8 +498,7 @@ srs_config srsran::config_helpers::make_default_srs_config(const cell_config_bui res.freq_hop.b_hop = 0; res.grp_or_seq_hop = srs_group_or_sequence_hopping::neither; res.res_type = srs_resource_type::aperiodic; - - res.sequence_id = params.pci; + res.sequence_id = params.pci; cfg.srs_res_set_list.emplace_back(); // TODO: Verify correctness of the config based on what we support. diff --git a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp index cdd0124b38..97f1aa535c 100644 --- a/tests/unittests/du_manager/du_ran_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_ran_resource_manager_test.cpp @@ -787,604 +787,6 @@ INSTANTIATE_TEST_SUITE_P( // clang-format on ); -///////// Test DU RAN resource manager for SRS resources ///////// - -namespace { - -struct srs_params { - // If set, it's a TDD cell and the parameters indicates the number of UL symbols in the flexible slot. - std::optional nof_ul_symbols_p1; - bool test_optimality = false; -}; - -std::ostream& operator<<(std::ostream& out, const srs_params& params) -{ - if (params.nof_ul_symbols_p1.has_value()) { - out << fmt::format("TDD_nof_ul_symbols_p1_{}_test_optimality_{}", - params.nof_ul_symbols_p1.value(), - params.test_optimality ? "true" : "false"); - } else { - out << fmt::format("FDD_test_optimality_{}", params.test_optimality ? "true" : "false"); - } - return out; -} - -} // namespace - -static cell_config_builder_params make_cell_cfg_params(const srs_params& params) -{ - const bool is_tdd = params.nof_ul_symbols_p1.has_value(); - cell_config_builder_params cell_params = {.dl_f_ref_arfcn = not is_tdd ? 365000U : 520002U}; - if (is_tdd) { - auto& tdd_cfg = cell_params.tdd_ul_dl_cfg_common.emplace(); - tdd_cfg.pattern1.dl_ul_tx_period_nof_slots = 10; - tdd_cfg.pattern1.nof_dl_slots = 7; - tdd_cfg.pattern1.nof_dl_symbols = 2; - tdd_cfg.pattern1.nof_ul_slots = 2; - tdd_cfg.pattern1.nof_ul_symbols = params.nof_ul_symbols_p1.value(); - tdd_cfg.ref_scs = subcarrier_spacing::kHz30; - } - - return cell_params; -} - -static du_cell_config make_srs_base_du_cell_config(const cell_config_builder_params& params) -{ - // This function generates a configuration which would potentially allow for a very large number of SRS resources. - du_cell_config du_cfg = config_helpers::make_default_du_cell_config(params); - auto& srs_cfg = du_cfg.srs_cfg; - - // Generates a random SRS configuration. - srs_cfg.tx_comb = test_rgen::bernoulli(0.5) ? tx_comb_size::n2 : tx_comb_size::n4; - srs_cfg.max_nof_symbols = test_rgen::uniform_int(1U, 6U); - std::array nof_symb_values = {srs_nof_symbols::n1, srs_nof_symbols::n2, srs_nof_symbols::n4}; - srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; - while (srs_cfg.nof_symbols > srs_cfg.max_nof_symbols) { - srs_cfg.nof_symbols = nof_symb_values[test_rgen::uniform_int(0, nof_symb_values.size() - 1)]; - } - - // The TX comb cyclic shift value depends on the TX comb size. - if (srs_cfg.tx_comb == srsran::tx_comb_size::n2) { - std::array srs_cyclic_shift_values = { - nof_cyclic_shifts::no_cyclic_shift, nof_cyclic_shifts::two, nof_cyclic_shifts::four}; - srs_cfg.cyclic_shift_reuse_factor = - srs_cyclic_shift_values[test_rgen::uniform_int(0, srs_cyclic_shift_values.size() - 1)]; - } else { - std::array srs_cyclic_shift_values = {nof_cyclic_shifts::no_cyclic_shift, - nof_cyclic_shifts::two, - nof_cyclic_shifts::three, - nof_cyclic_shifts::four, - nof_cyclic_shifts::six, - nof_cyclic_shifts::twelve}; - srs_cfg.cyclic_shift_reuse_factor = - srs_cyclic_shift_values[test_rgen::uniform_int(0, srs_cyclic_shift_values.size() - 1)]; - } - // [Implementation-defined] These are the values in the gNB, \ref sequence_id_reuse_factor. - std::array srs_seq_id_values = {1, 2, 3, 5, 6, 10, 15, 30}; - srs_cfg.sequence_id_reuse_factor = - srs_seq_id_values[test_rgen::uniform_int(0, srs_seq_id_values.size() - 1)]; - - if (du_cfg.tdd_ul_dl_cfg_common.has_value()) { - std::array period_values = {srs_periodicity::sl10, - srs_periodicity::sl20, - srs_periodicity::sl40, - srs_periodicity::sl80, - srs_periodicity::sl160, - srs_periodicity::sl320, - srs_periodicity::sl640, - srs_periodicity::sl1280}; - srs_cfg.srs_period.emplace(period_values[test_rgen::uniform_int(0, period_values.size() - 1)]); - } else { - std::array period_values = {srs_periodicity::sl1, - srs_periodicity::sl2, - srs_periodicity::sl4, - srs_periodicity::sl5, - srs_periodicity::sl8, - srs_periodicity::sl10, - srs_periodicity::sl16, - srs_periodicity::sl20, - srs_periodicity::sl32, - srs_periodicity::sl40}; - srs_cfg.srs_period.emplace(period_values[test_rgen::uniform_int(0, period_values.size() - 1)]); - } - - return du_cfg; -} - -static du_cell_config make_srs_du_cell_config(const cell_config_builder_params& params, bool limit_srs_res) -{ - auto du_cfg = make_srs_base_du_cell_config(params); - - // For the optimality test, we to have a configuration that doesn't allow for more than 1024 SRS resources. - if (not limit_srs_res) { - return du_cfg; - } - - // This function calculates the total number of SRS resources that can be potentially allocated in the cell with the - // given SRS parameters. - auto tot_num_srs_res = [&du_cfg]() { - auto& tdd_cfg = du_cfg.tdd_ul_dl_cfg_common; - auto& srs_cfg = du_cfg.srs_cfg; - // This is the number of SRS resources per symbol interval. A symbol interval is an interval where the SRS resource - // can be placed within a slot and its width (or length) is given by the corresponding SRS parameter \c nof_symb in - // the SRS configuration. - const unsigned nof_res_per_symb_interval = srs_cfg.sequence_id_reuse_factor * - static_cast(srs_cfg.cyclic_shift_reuse_factor) * - static_cast(srs_cfg.tx_comb); - - // This "number of symbols intervals" counts all the symbols intervals within the SRS period. - unsigned nof_symb_intervals = 0; - - // The number of symbols interval per slot depends on whether it's FDD or TDD. - if (not tdd_cfg.has_value()) { - // In FDD, in an SRS period we can "max_nof_symbols / nof_symbols" intervals per slot. - nof_symb_intervals = srs_cfg.max_nof_symbols.to_uint() / static_cast(srs_cfg.nof_symbols) * - static_cast(srs_cfg.srs_period.value()); - } else { - // In TDD, in an SRS period we can "max_nof_symbols / nof_symbols" intervals per UL slot; in addition to this, the - // partially-UL slots can have extra symbols intervals, up to a maximum of 6U, which is the max number of symbols - // usable for SRS resources. - nof_symb_intervals = - (srs_cfg.max_nof_symbols.to_uint() / static_cast(srs_cfg.nof_symbols)) * - tdd_cfg->pattern1.nof_ul_slots * - (static_cast(srs_cfg.srs_period.value()) / tdd_cfg->pattern1.dl_ul_tx_period_nof_slots); - if (tdd_cfg->pattern1.nof_ul_symbols != 0) { - nof_symb_intervals += - (std::min(tdd_cfg->pattern1.nof_ul_symbols, srs_cfg.max_nof_symbols.max()) / - static_cast(srs_cfg.nof_symbols)) * - (static_cast(srs_cfg.srs_period.value()) / tdd_cfg->pattern1.dl_ul_tx_period_nof_slots); - } - } - - // Return the total number of SRS resources. - return nof_symb_intervals * nof_res_per_symb_interval; - }; - - while (tot_num_srs_res() > static_cast(MAX_NOF_DU_UES)) { - du_cfg = make_srs_base_du_cell_config(params); - } - - return du_cfg; -} - -class du_srs_resource_manager_tester : public ::testing::TestWithParam -{ -protected: - explicit du_srs_resource_manager_tester(cell_config_builder_params params_ = make_cell_cfg_params(GetParam())) : - params(params_), - cell_cfg_list({make_srs_du_cell_config(params_, GetParam().test_optimality)}), - srs_params(cell_cfg_list[0].srs_cfg), - du_srs_res_mng(cell_cfg_list) - { - } - - std::optional add_ue(du_ue_index_t ue_idx) - { - if (ue_idx >= MAX_NOF_DU_UES) { - return std::nullopt; - } - - cell_group_config cell_grp_cfg; - std::unique_ptr cell_grp_cfg_ptr = std::make_unique(); - cell_grp_cfg.cells.insert( - serv_cell_index_t::SERVING_CELL_PCELL_IDX, - cell_config_dedicated{serv_cell_index_t::SERVING_CELL_PCELL_IDX, - config_helpers::create_default_initial_ue_serving_cell_config(params)}); - ues.insert(ue_idx, cell_grp_cfg); - auto& ue = ues[ue_idx]; - - // Reset the SRS config before allocating resources. - ue.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.reset(); - - bool res = du_srs_res_mng.alloc_resources(ue); - if (res) { - return ue; - } - // If the allocation was not possible, remove the UE. - ues.erase(ue_idx); - return std::nullopt; - } - - // Helper struct that keeps track of the SRS resource parameter assigned to the UEs. - struct srs_res_params { - unsigned offset; - unsigned tx_comb_offset; - ofdm_symbol_range symbols; - unsigned sequence_id; - unsigned cs; - - // Constructor for the srs_res_params struct given srs_resource. - explicit srs_res_params(const srs_config::srs_resource& srs_res) : - offset(srs_res.periodicity_and_offset->offset), - tx_comb_offset(srs_res.tx_comb.tx_comb_offset), - symbols(ofdm_symbol_range{NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res.res_mapping.start_pos - 1, - NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - srs_res.res_mapping.start_pos - 1 + - srs_res.res_mapping.nof_symb}), - sequence_id(srs_res.sequence_id), - cs(srs_res.tx_comb.tx_comb_cyclic_shift) - { - } - - // Returns true is SRS resource collides with another SRS resource; it is used to check if the SRS resources are - // orthogonal. - bool collides(const srs_res_params& rhs) const - { - return offset == rhs.offset and tx_comb_offset == rhs.tx_comb_offset and symbols.overlaps(rhs.symbols) and - sequence_id == rhs.sequence_id and cs == rhs.cs; - } - - bool operator==(const srs_res_params& rhs) const - { - return offset == rhs.offset and tx_comb_offset == rhs.tx_comb_offset and symbols == rhs.symbols and - sequence_id == rhs.sequence_id and cs == rhs.cs; - } - - bool operator!=(const srs_res_params& rhs) const { return not operator==(rhs); } - }; - - // Helper that computes the C_SRS parameter (see Section 6.4.1.4.3, TS 38.211). - unsigned compute_c_srs() const - { - // In this test, we only consider the case where B_SRS is 0. - const uint8_t b_srs = 0U; - unsigned candidate_c_srs = 0U; - unsigned candidate_m_srs = 0U; - // Spans over Table 6.4.1.4.3-1 in TS 38.211 and find the smallest C_SRS that maximizes m_srs_0 under the - // constraint of m_SRS <= nof_BW_RBs. - for (unsigned c_srs_it = 0; c_srs_it != 64; ++c_srs_it) { - std::optional srs_cfg = srs_configuration_get(c_srs_it, b_srs); - srsran_assert(srs_cfg.has_value(), "C_SRS is required for this unittest"); - if (srs_cfg.value().m_srs <= cell_cfg_list[0].ul_cfg_common.init_ul_bwp.generic_params.crbs.length() and - srs_cfg.value().m_srs > candidate_m_srs) { - candidate_m_srs = srs_cfg->m_srs; - candidate_c_srs = c_srs_it; - } - } - return candidate_c_srs; - } - - // Helper that computes the Frequency Shift parameter (see Section 6.4.1.4.3, TS 38.211). - unsigned compute_freq_shift() const - { - // The function computes the frequency shift so that the SRS resources are placed in the center of the band. - unsigned c_srs = compute_c_srs(); - unsigned ul_bw_nof_rbs = cell_cfg_list[0].ul_cfg_common.init_ul_bwp.generic_params.crbs.length(); - const auto srs_cfg = srs_configuration_get(c_srs, 0U); - srsran_assert(srs_cfg.has_value(), "C_SRS is required for this unittest"); - return (ul_bw_nof_rbs - srs_cfg.value().m_srs) / 2U; - } - - cell_config_builder_params params; - std::vector cell_cfg_list; - // This is a reference to the first element of cell_cfg_list's SRS config. - const srs_builder_params& srs_params; - du_srs_policy_max_ul_rate du_srs_res_mng; - slotted_array ues; -}; - -static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) -{ - const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0; -} - -static bool is_partially_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) -{ - const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - const unsigned nof_symbols = srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); - return nof_symbols != 0 and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; -} - -TEST_P(du_srs_resource_manager_tester, ue_are_assigned_orthogonal_srs_resources) -{ - du_ue_index_t next_ue_index = to_du_ue_index(0); - - // Keeps track of which SRS resources have been assigned to the UEs. - std::vector used_srs_resources; - // > Created UEs have unique SRS resources. - for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { - std::optional ue = add_ue(to_du_ue_index(i)); - if (not ue.has_value()) { - break; - } - - // Check if the SRS has been assigned to the UE. - const auto& srs_res_list = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list; - ASSERT_FALSE(srs_res_list.empty()); - // Check if the SRS resource collides (i.e., is not orthogonal) with any other SRS resource. - const auto& srs_res = srs_res_list[0]; - const srs_res_params res_params(srs_res); - ASSERT_FALSE(std::any_of(used_srs_resources.begin(), - used_srs_resources.end(), - [&res_params](const srs_res_params& res) { return res.collides(res_params); })); - - used_srs_resources.push_back(res_params); - next_ue_index = to_du_ue_index((unsigned)next_ue_index + 1); - } - - // Erase a random UE and attempt. - const du_ue_index_t ue_idx_to_rem = to_du_ue_index(test_rgen::uniform_int(0, ues.size() - 1)); - du_srs_res_mng.dealloc_resources(ues[ue_idx_to_rem]); - auto& ue_to_be_removed = ues[ue_idx_to_rem]; - // First, find the SRS resource of the ue to be removed and removed it from the vector of used resources. - srs_res_params srs_res_to_be_removed( - ue_to_be_removed.cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list[0]); - auto res_to_remove_it = std::find(used_srs_resources.begin(), used_srs_resources.end(), srs_res_to_be_removed); - ASSERT_FALSE(res_to_remove_it == used_srs_resources.end()); - used_srs_resources.erase(res_to_remove_it); - ues.erase(ue_idx_to_rem); - - // Attempt a new allocation and verify it is successful. - next_ue_index = to_du_ue_index((unsigned)next_ue_index + 1); - std::optional ue = add_ue(ue_idx_to_rem); - ASSERT_TRUE(ue.has_value()); - - // Check if the SRS has been assigned to the UE. - const auto& srs_res_list = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg->srs_res_list; - ASSERT_FALSE(srs_res_list.empty()); - // Check if the SRS resource collides (i.e., is not orthogonal) with any other SRS resource. - const auto& srs_res = srs_res_list[0]; - const srs_res_params res_params(srs_res); - ASSERT_FALSE(std::any_of(used_srs_resources.begin(), - used_srs_resources.end(), - [&res_params](const srs_res_params& res) { return res.collides(res_params); })); -} - -TEST_P(du_srs_resource_manager_tester, srs_resources_parameters_are_valid) -{ - // > Created UEs have unique SRS resources. - for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { - std::optional ue = add_ue(to_du_ue_index(i)); - if (not ue.has_value()) { - break; - } - - // Verify all parameters of the SRS resource are as expected. - ASSERT_TRUE(ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); - const auto& ue_srs_config = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); - // Verify first the SRS resource set list. - ASSERT_EQ(ue_srs_config.srs_res_set_list.size(), 1U); - ASSERT_EQ(ue_srs_config.srs_res_set_list[0].id, 0U); - ASSERT_TRUE(std::holds_alternative( - ue_srs_config.srs_res_set_list[0].res_type)); - ASSERT_EQ(ue_srs_config.srs_res_set_list[0].srs_res_id_list.size(), 1U); - ASSERT_EQ(ue_srs_config.srs_res_set_list[0].srs_res_id_list[0], 0U); - ASSERT_EQ(ue_srs_config.srs_res_list.size(), 1U); - const auto& srs_res = ue_srs_config.srs_res_list[0]; - ASSERT_EQ(srs_res.id.ue_res_id, static_cast(0U)); - ASSERT_TRUE(srs_res.periodicity_and_offset.has_value()); - ASSERT_EQ(srs_res.periodicity_and_offset->period, srs_params.srs_period.value()); - ASSERT_LT(srs_res.periodicity_and_offset->offset, static_cast(srs_res.periodicity_and_offset->period)); - if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value()) { - ASSERT_TRUE(is_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())); - } - ASSERT_LT(srs_res.tx_comb.tx_comb_offset, static_cast(srs_res.tx_comb.size)); - ASSERT_LT(srs_res.tx_comb.tx_comb_cyclic_shift, srs_res.tx_comb.size == tx_comb_size::n2 ? 8U : 12U); - - ASSERT_EQ(srs_res.freq_hop.c_srs, compute_c_srs()); - ASSERT_EQ(srs_res.freq_hop.b_srs, 0U); - ASSERT_EQ(srs_res.freq_hop.b_hop, 0U); - ASSERT_EQ(srs_res.freq_domain_shift, compute_freq_shift()); - ASSERT_EQ(srs_res.freq_domain_pos, 0U); - - // Verify the symbols, depending on whether it's FDD, or TDD. - ASSERT_EQ(srs_res.res_mapping.nof_symb, srs_params.nof_symbols); - if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value() and - is_partially_ul_slot(srs_res.periodicity_and_offset->offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { - ASSERT_LT(srs_res.res_mapping.start_pos, cell_cfg_list[0].tdd_ul_dl_cfg_common.value().pattern1.nof_ul_symbols); - } else { - ASSERT_LT(srs_res.res_mapping.start_pos, srs_params.max_nof_symbols.to_uint()); - } - } -} - -INSTANTIATE_TEST_SUITE_P(test_du_srs_res_mng_for_different_ul_symbols, - du_srs_resource_manager_tester, - ::testing::Values(srs_params{.nof_ul_symbols_p1 = std::nullopt}, - srs_params{.nof_ul_symbols_p1 = 0U}, - srs_params{.nof_ul_symbols_p1 = 1U}, - srs_params{.nof_ul_symbols_p1 = 2U}, - srs_params{.nof_ul_symbols_p1 = 3U}, - srs_params{.nof_ul_symbols_p1 = 4U}, - srs_params{.nof_ul_symbols_p1 = 5U}, - srs_params{.nof_ul_symbols_p1 = 6U}, - srs_params{.nof_ul_symbols_p1 = 7U}), - [](const testing::TestParamInfo& params_item) { - return fmt::format("{}", params_item.param); - }); - -///////// Test the optimality of DU SRS resource manager policy ///////// - -class du_srs_resource_manager_tester_optimality : public du_srs_resource_manager_tester -{ -protected: - explicit du_srs_resource_manager_tester_optimality() - { - nof_srs_res_per_symb_interval = static_cast(srs_params.tx_comb) * - static_cast(srs_params.cyclic_shift_reuse_factor) * - static_cast(srs_params.sequence_id_reuse_factor); - srs_res_tracker.reserve(static_cast(srs_params.srs_period.value())); - - // Build the SRS resource tracker. - for (unsigned offset = 0; offset != static_cast(srs_params.srs_period.value()); ++offset) { - if (cell_cfg_list[0].tdd_ul_dl_cfg_common.has_value()) { - const auto& tdd_cfg = cell_cfg_list[0].tdd_ul_dl_cfg_common.value(); - - if (not is_ul_slot(offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { - // In TDD, no SRS resources can be allocated in DL slots. - srs_res_tracker.emplace_back(0U); - } else if (is_partially_ul_slot(offset, cell_cfg_list[0].tdd_ul_dl_cfg_common.value())) { - const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - const unsigned nof_ul_symbols = - srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); - // The number of symbols intervals is limited by the number of symbols where the SRS can be placed. - const unsigned nof_intervals = std::min(nof_ul_symbols / static_cast(srs_params.nof_symbols), - srs_params.max_nof_symbols.max()); - srs_res_tracker.emplace_back(nof_intervals); - } else { - const unsigned nof_intervals = - srs_params.max_nof_symbols.to_uint() / static_cast(srs_params.nof_symbols); - srs_res_tracker.emplace_back(nof_intervals); - } - } - // FDD case. - else { - const unsigned nof_intervals = - srs_params.max_nof_symbols.to_uint() / static_cast(srs_params.nof_symbols); - srs_res_tracker.emplace_back(nof_intervals); - } - } - } - - // Helper struct that keeps track of the number of SRS resources per symbol interval for a given offset. - struct res_per_slot_tracker { - explicit res_per_slot_tracker(unsigned nof_srs_symb_intervals_per_slot_) : - nof_srs_symb_intervals_per_slot(nof_srs_symb_intervals_per_slot_) - { - // Initialize the vector with zeros, as at the beginning no SRS resources have been allocated. - res_per_symb_interval.assign(nof_srs_symb_intervals_per_slot, 0U); - } - - const unsigned nof_srs_symb_intervals_per_slot; - // This vector keeps track of the number of SRS resources per symbol interval. The symbol interval with index 0 is - // the last one in the slot; the symbol interval with index 1 is the second to last, and so on. - std::vector res_per_symb_interval; - }; - - // The number of SRS resources per symbol interval, which depends on the TX comb size, on the cyclic shift reuse - // factor, and on the sequence ID reuse factor. - unsigned nof_srs_res_per_symb_interval = 0; - // This vector keeps track of the number of SRS resources per symbol interval for each offset. - std::vector srs_res_tracker; - - // Save the SRS resource allocation in the tracker. - void track_srs_res_alloc(const srs_config::srs_resource& srs_res) - { - srsran_assert(srs_res.periodicity_and_offset.has_value(), "SRS resource must have a periodicity and offset"); - const unsigned srs_offset = srs_res.periodicity_and_offset->offset; - const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); - srsran_assert(interval_idx < srs_res_tracker[srs_offset].res_per_symb_interval.size(), - "SRS resource must have a periodicity and offset"); - ++srs_res_tracker[srs_offset].res_per_symb_interval[interval_idx]; - } - - // Check if there is any partially-UL slot that has not completely filled with SRS resources. - bool has_free_partial_ul_slots() - { - for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { - if (not is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value())) { - continue; - } - if (std::any_of(srs_res_tracker[n].res_per_symb_interval.begin(), - srs_res_tracker[n].res_per_symb_interval.end(), - [this](unsigned cnt) { return cnt < nof_srs_res_per_symb_interval; })) { - return true; - } - } - return false; - } - - // Check if all the symbol intervals with index lower than the one of the given SRS resource have - // been used (in fully-UL slots). - bool all_lower_intervals_used(const srs_config::srs_resource& srs_res) - { - const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); - if (interval_idx == 0) { - return true; - } - - for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { - if (params.tdd_ul_dl_cfg_common.has_value() and (not is_ul_slot(n, params.tdd_ul_dl_cfg_common.value()) or - is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value()))) { - continue; - } - if (std::any_of(srs_res_tracker[n].res_per_symb_interval.begin(), - srs_res_tracker[n].res_per_symb_interval.begin() + interval_idx, - [this](unsigned cnt) { return cnt < nof_srs_res_per_symb_interval; })) { - return false; - } - } - return true; - } - - // Check if there is any symbol interval of the same index of the one of the given SRS resource that is not empty, but - // not full either. - bool non_empty_non_full_interval(const srs_config::srs_resource& srs_res) - { - const unsigned interval_idx = srs_res.res_mapping.start_pos / static_cast(srs_res.res_mapping.nof_symb); - for (unsigned n = 0; n != srs_res_tracker.size(); ++n) { - // Skip the slot where the SRS resource has been allocated, otherwise this will always return true. - if (n == srs_res.periodicity_and_offset->offset) { - continue; - } - if (params.tdd_ul_dl_cfg_common.has_value() and (not is_ul_slot(n, params.tdd_ul_dl_cfg_common.value()) or - is_partially_ul_slot(n, params.tdd_ul_dl_cfg_common.value()))) { - continue; - } - srsran_assert(interval_idx < srs_res_tracker[n].res_per_symb_interval.size(), - "Interval index exceeds the size of the vector"); - if (srs_res_tracker[n].res_per_symb_interval[interval_idx] > 0U and - srs_res_tracker[n].res_per_symb_interval[interval_idx] < nof_srs_res_per_symb_interval) { - return true; - } - } - return false; - } -}; - -TEST_P(du_srs_resource_manager_tester_optimality, srs_are_assigned_according_to_class_policy) -{ - // > Created UEs have unique SRS resources. - for (unsigned i = 0; i != MAX_NOF_DU_UES; ++i) { - std::optional ue = add_ue(to_du_ue_index(i)); - if (not ue.has_value()) { - break; - } - - // Verify all parameters of the SRS resource are as expected. - ASSERT_TRUE(ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.has_value()); - const auto& ue_srs_config = ue.value().cells[0].serv_cell_cfg.ul_config->init_ul_bwp.srs_cfg.value(); - const auto& srs_res = ue_srs_config.srs_res_list[0]; - - // Save the SRS resource allocation in the tracker. - track_srs_res_alloc(srs_res); - - // The SRS allocation assigns resources according to the policy: - // - If there is a partially-UL slot available, then the SRS resources are allocated in the partially-UL slots. - // - If there are no partially-UL slots, then the SRS resources are allocated in the fully-UL slots. - // - If there are no fully-UL slots with a symbol interval of index i available, then the SRS resources are - // allocated in a symbol interval of index i+1, in any slot. - // - If there is a fully-UL slots with a symbol interval of index i available that has already SRS resources - // allocated, but has not been completely filled, then the SRS resources are allocated in that slot. - if (params.tdd_ul_dl_cfg_common.has_value()) { - if (not is_partially_ul_slot(srs_res.periodicity_and_offset.value().offset, - params.tdd_ul_dl_cfg_common.value())) { - ASSERT_FALSE(has_free_partial_ul_slots()); - ASSERT_TRUE(all_lower_intervals_used(srs_res)); - ASSERT_FALSE(non_empty_non_full_interval(srs_res)); - } - } else { - ASSERT_TRUE(all_lower_intervals_used(srs_res)); - ASSERT_FALSE(non_empty_non_full_interval(srs_res)); - } - } -} - -INSTANTIATE_TEST_SUITE_P(test_du_srs_res_mng_for_different_ul_symbols, - du_srs_resource_manager_tester_optimality, - ::testing::Values(srs_params{.nof_ul_symbols_p1 = std::nullopt, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 0U, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 1U, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 2U, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 3U, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 4U, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 5U, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 6U, .test_optimality = true}, - srs_params{.nof_ul_symbols_p1 = 7U, .test_optimality = true}), - [](const testing::TestParamInfo& params_item) { - return fmt::format("{}", params_item.param); - }); - ///////// Test the DU RAN resource manager for both PUCCH and SRS resources ///////// // This helper builds a DU cell configuration with a custom PUCCH and SRS configuration. The input parameter diff --git a/tests/unittests/du_manager/du_srs_resource_manager_test.cpp b/tests/unittests/du_manager/du_srs_resource_manager_test.cpp index 2d3dc78229..7263a7e1aa 100644 --- a/tests/unittests/du_manager/du_srs_resource_manager_test.cpp +++ b/tests/unittests/du_manager/du_srs_resource_manager_test.cpp @@ -39,6 +39,18 @@ std::ostream& operator<<(std::ostream& out, const srs_params& params) } // namespace +static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + return has_active_tdd_ul_symbols(tdd_cfg, slot_index); +} + +static bool is_partially_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) +{ + const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); + return is_tdd_partial_ul_slot(tdd_cfg, slot_index); +} + static cell_config_builder_params make_cell_cfg_params(const srs_params& params) { const bool is_tdd = params.nof_ul_symbols_p1.has_value(); @@ -290,19 +302,6 @@ class du_srs_resource_manager_tester : public ::testing::TestWithParam ues; }; -static bool is_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) -{ - const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - return srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length() != 0; -} - -static bool is_partially_ul_slot(unsigned offset, const tdd_ul_dl_config_common& tdd_cfg) -{ - const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe(tdd_cfg.ref_scs)); - const unsigned nof_symbols = srsran::get_active_tdd_ul_symbols(tdd_cfg, slot_index, cyclic_prefix::NORMAL).length(); - return nof_symbols != 0 and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; -} - TEST_P(du_srs_resource_manager_tester, ue_are_assigned_orthogonal_srs_resources) { du_ue_index_t next_ue_index = to_du_ue_index(0);